2013-04-05 5 views
3

У меня есть блок catch try в моем sp с инструкцией insert в try. код ошибки проверки catch, если он является нарушением pk, если он затем обновляется. но иногда я получаю «Текущая транзакция не может быть зафиксирована и не может поддерживать операции, которые записываются в файл журнала. Откат транзакции.установить xact_abort и попытаться поймать вместе

Неопределенная транзакция обнаружена в конце партии. Сделка отменяется». поэтому я добавил xact_abort, но тогда я продолжаю получать «Счет транзакции после того, как EXECUTE указывает несоответствующее число операторов BEGIN и COMMIT». и я нашел это. http://www.ashishsheth.com/post/2009/08/14/Set-XACT_ABORT-ON-and-TryCatch-block-in-Sql-Server-2005.aspx

если это правда. будет ли мой код catch не запущен, если в моем блоке try произошла ошибка с xact_abort?

ответ

9

Это не так, по крайней мере, с SQL Server 2008, что SET XACT_ABORT ON приведет к ошибке пропустить CATCH блок:

Вот код, я попытался с помощью базы данных Борей

SET XACT_ABORT OFF 
BEGIN TRY 
    SELECT 1, @@TRANCOUNT 
BEGIN TRAN 
    UPDATE [dbo].[Categories] 
    SET Description='BLAH' 
    WHERE [CategoryID]=2 
    SELECT 2, @@TRANCOUNT 

    SELECT 1/0 as whoops 


COMMIT 
    SELECT 3, @@TRANCOUNT 

END TRY 
BEGIN CATCH 
    SELECT 'In Catch. Error occured', 4, @@TRANCOUNT 

    IF (XACT_STATE()) = 0 
    BEGIN 
     SELECT 
      N'There is no transaction' 

    END; 


    IF (XACT_STATE()) = -1 
    BEGIN 
     SELECT 
      N'The transaction is in an uncommittable state.' + 
      'Rolling back transaction.' 
     ROLLBACK TRANSACTION; 
    END; 

    -- Test whether the transaction is committable. 
    IF (XACT_STATE()) = 1 
    BEGIN 
     SELECT 
      N'The transaction is committable.' + 
      'Committing transaction.' 
     COMMIT TRANSACTION; 
    END; 

END CATCH 

Это, очевидно, приведет к ошибке при нажатии на инструкцию SELECT 1/0. Если SET XACT_ABORT OFF, когда достигнут блок CATCH, значение, возвращаемое функцией XACT_STATE(), равно 1, что приводит к запуску кода, который COMMIT выполняет транзакцию. Когда SET XACT_ABORT включен, значение, возвращаемое, в блоке CATCH равно -1, поэтому выполняется код, который ROLL возвращает транзакцию.

Это основано на:

http://msdn.microsoft.com/en-us/library/ms175976.aspx

+1

Извините, что я опоздал на вечеринку ... Я согласен с Майклом, и подвох блок «» выполняется до отката, если у вас есть XACT_ABORT включен. Самое смешное в том, что все, что вы делаете в блоке catch, все равно откатывается, поэтому может показаться, что вы даже не выполняете все, что там есть. Если вы поместите инструкцию select в блок CATCH, вы увидите, что она выплевывается в SSMS, даже если будет вызвана ошибка. – Eli

Смежные вопросы