Выполнение хранимой процедуры внутри транзакции BEGIN/END

Если я создаю хранимую процедуру в SQL и вызываю ее (EXEC spStoredProcedure) в транзакции BEGIN/END эта другая хранимая процедура также попадает в транзакцию?

Я не знал, работает ли это как try/catches в C#.

7 ответов


да все то, что вы делаете между началом транзакции и фиксацией (или откатом), является частью транзакции.


звучит здорово, спасибо. Я закончил делать что-то вроде этого (потому что я на 05)

    BEGIN TRY
       BEGIN TRANSACTION

       DO SOMETHING

       COMMIT
    END TRY
    BEGIN CATCH
      IF @@TRANCOUNT > 0
         ROLLBACK

      -- Raise an error with the details of the exception
      DECLARE @ErrMsg nvarchar(4000), @ErrSeverity int
      SELECT @ErrMsg = ERROR_MESSAGE(),
             @ErrSeverity = ERROR_SEVERITY()

      RAISERROR(@ErrMsg, @ErrSeverity, 1)
    END CATCH

Я считаю, что в MS SQL Server выполнение хранимой процедуры произойдет в рамках транзакции, но будьте очень осторожны с этим. Если у вас есть вложенные транзакции (т. е. транзакция вне хранимой процедуры и другая транзакция внутри хранимой процедуры), откат повлияет на все транзакции, а не только на ближайшую заключительную транзакцию.


Как упоминал Крис,вы должны быть осторожны при откате транзакции.

в частности, это:

IF @@TRANCOUNT > 0 ROLLBACK

не всегда то, что вы хотите. Вы могли бы сделать что-то подобное

IF(@@TRANCOUNT = 1) ROLLBACK TRAN
ELSE IF(@@TRANCOUNT > 1) COMMIT TRAN
RETURN @error

таким образом, вызывающий proc может проверить возвращаемое значение из хранимой процедуры и определить, хочет ли он в любом случае зафиксировать или продолжить пузырить ошибку.

причина в том, что "COMMIT" просто уменьшит ваш счетчик транзакций. Как только он уменьшит счетчик транзакций до нуля, произойдет фактическая фиксация.


As Крис и Джеймс упомянуто, вам нужно быть осторожным при работе с вложенными транзакциями. Существует множество очень хороших статей на тему транзакций, написанных Дон Петерсон on SQL Server Central, я бы рекомендовал прочитать их:

здесь:


Да, все вложенные вызовы хранимых процедур включена в объем сделки. Если вы используете SQL Server 2005 или выше, вы можете использовать Try...Лови тоже. здесь более подробно об этом.


@Chris, я этого не знал.

когда googling для получения дополнительной информации, я наткнулся этой - вы можете установить "savepoints", который может быть откат без отката всей транзакции.

может быть полезно в этой ситуации.