COMMIT только если транзакция была начата.
Таким образом, вы можете сначала проверить открытую транзакцию и запретить чтение. Это гарантирует, что ни одна транзакция не будет открыта для отката. Я использовал XACT_STATE () здесь
Использование SET XACT_ABORT ON и TRY / CATCH также будет означать, что INSERT для ведения журнала должен произойти также до того, как произойдет чтение. Любые ошибки на всех на INSERT перейдут в блок CATCH. Таким образом, нет чтения, и ошибка регистрации сама по себе также не может быть зарегистрирована.
Итак: это ваша гарантия «только для чтения, если зарегистрирован»
Наличие явной транзакции не помогает: вставка в любом случае является атомарным действием. И если вызываемый открывает транзакцию, запись в журнале может быть откатана
CREATE PROC getSecretStuff
AS
SET NOCOUNT, XACT_ABORT ON;
BEGIN TRY
IF XACT_STATE() <> 0
RAISERRROR ('Call not allowed in an active transaction', 16, 1)
INSERT into AUDIT_LOG(ACCOUNT, TSTAMP)
VALUES(SYSTEM_USER, getdate());
--Now fetch data
SELECT x,y,z from sensitive_info;
END TRY
BEGIN CATCH
-- error handling etc
END CATCH
GO