Выполнение хранимой процедуры внутри BEGIN/END TRANSACTION
Если я создаю хранимую процедуру в SQL и вызываю ее (EXEC spStoredProcedure
) в рамках BEGIN/END TRANSACTION эта другая хранимая процедура также попадает в транзакцию?
Я не знал, работает ли он как try/catch в C#.
7 ответов
Да, все, что вы делаете между Begin Transaction и Commit (или Rollback), является частью транзакции.
Звучит отлично, спасибо большое. Я закончил тем, что делал что-то подобное (потому что я на 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
Таким образом, вызывающий процесс может проверить возвращаемое значение из хранимой процедуры и определить, хочет ли он все равно зафиксировать или продолжать выдавать ошибку.
Причина в том, что COMMIT просто уменьшит счетчик транзакций. Как только он уменьшает счетчик транзакций до нуля, происходит фактическое принятие.
Как упоминали Крис и Джеймс, вы должны быть осторожны при работе с вложенными транзакциями. Существует множество очень хороших статей на тему транзакций, написанных Доном Петерсоном на SQL Server Centra. Я бы порекомендовал прочитать их:
Здесь находятся:
Да, все вложенные вызовы хранимых процедур включены в объем транзакции. Если вы используете SQL Server 2005 или более позднюю версию, вы также можете использовать Try...Catch. Вот более подробно об этом.
@ Крис, я этого не знал.
При поиске дополнительной информации я наткнулся на это - вы можете установить "точки сохранения", к которым можно вернуться без отката всей транзакции.
Может быть полезно в этой ситуации.