SQL Server не соответствует количеству вложенных транзакций операторов BEGIN и COMMIT
Я следовал рекомендованному шаблону для обработки ошибок в транзакции, которая должна работать, когда он выполняется внутри существующей транзакции.
Это мой шаблон
CREATE PROCEDURE DoSomething
AS
BEGIN
SET NOCOUNT ON
DECLARE @trans INTEGER = @@TRANCOUNT
IF (@trans > 0)
SAVE TRANSACTION SavePoint
ELSE
BEGIN TRANSACTION
BEGIN TRY
-- code with a check that does a THROW if the requirements aren't met
IF (@trans = 0)
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF (@trans > 0)
ROLLBACK TRANSACTION SavePoint
ELSE
ROLLBACK TRANSACTION
;THROW
END CATCH
END
Если я заменю THROW в блоке TRY на RAISERROR, проблема останется.
Результаты теста:
Сценарий сбоя EXEC в транзакции: правильный результат (выдает правильное сообщение об ошибке)
Сценарий успеха EXEC в транзакции: выдает неожиданную ошибку.
Число транзакций после EXECUTE указывает на несовпадающее количество операторов BEGIN и COMMIT. Предыдущий счет = 1, текущий счет = 2.
Сценарий сбоя EXEC вне транзакции: выдает ожидаемую ошибку.
Сценарий успеха EXEC вне транзакции: выдает неожиданную ошибку. Ошибка та же, что и выше, но каждый раз, когда вы ее выполняете, она увеличивается на -1. Означает ли это, что каждый раз, когда больше вещей остается незафиксированным?
Вот как выглядит тест:
BEGIN TRANSACTION
EXEC ...
ROLLBACK TRANSACTION
Кто-нибудь знает, что идет не так?
1 ответ
Раскомментировать вар
CREATE PROCEDURE DoSomething
AS
BEGIN
SET NOCOUNT ON
DECLARE @trans INTEGER = @@TRANCOUNT
IF (@trans > 0)
SAVE TRANSACTION SavePoint
ELSE
BEGIN TRANSACTION
BEGIN TRY
DECLARE @f float;
SET @f = 0;
--var 1.
--print 1/0
--var 2.
print LOG(@f)
--var ok
--print 'ok'
END TRY
BEGIN CATCH
IF (@trans > 0 AND XACT_STATE() <> -1)
BEGIN
PRINT 'ROLLBACK SavePoint'
ROLLBACK TRANSACTION SavePoint
END
PRINT 'Error'
END CATCH
END
И выполнить
BEGIN TRANSACTION
EXEC DoSomething
IF XACT_STATE() = -1
BEGIN
PRINT 'ROLLBACK XACT'
ROLLBACK
END
IF @@TRANCOUNT > 0
BEGIN
PRINT 'COMMIT'
COMMIT
END