Выполнение хранимой процедуры внутри транзакции 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", который может быть откат без отката всей транзакции.
может быть полезно в этой ситуации.