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

@ Крис, я этого не знал.

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

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

Другие вопросы по тегам