为什么要在catch子句中提交事务?

时间:2010-05-14 17:07:00

标签: sql-server-2005 tsql

Microsoft在tsql中有以下try ... catch示例:

USE AdventureWorks;
GO

-- SET XACT_ABORT ON will render the transaction uncommittable
-- when the constraint violation occurs.
SET XACT_ABORT ON;

BEGIN TRY
    BEGIN TRANSACTION;
        -- A FOREIGN KEY constraint exists on this table. This 
        -- statement will generate a constraint violation error.
        DELETE FROM Production.Product
            WHERE ProductID = 980;

    -- If the delete operation succeeds, commit the transaction. The CATCH
    -- block will not execute.
    COMMIT TRANSACTION;
END TRY
BEGIN CATCH
    -- Test XACT_STATE for 0, 1, or -1.
    -- If 1, the transaction is committable.
    -- If -1, the transaction is uncommittable and should 
    --     be rolled back.
    -- XACT_STATE = 0 means there is no transaction and
    --     a commit or rollback operation would generate an error.

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

    -- Test whether the transaction is active and valid.
    IF (XACT_STATE()) = 1
    BEGIN
        PRINT 'The transaction is committable.' + 
              ' Committing transaction.'
        COMMIT TRANSACTION;   
    END;
END CATCH;
GO

以上示例的来源:Using TRY...CATCH in Transact-SQL

我不明白你为什么要提交一个导致异常的事务。似乎至少有9次你想要IF(XACT_STATE())!= 0 ROLLBACK TRANSACTION。你为什么要在一个干净的石板上取得部分成功呢?

1 个答案:

答案 0 :(得分:0)

此示例完全错误。有一个try-catch块来处理密钥副本并恢复并执行备用操作(可能是更新而不是插入)是可以理解的。但是如果成功的话,有一段代码可以使用COMMITS,但是会在发生错误的情况下使事务保持打开状态,甚至更多,默默地吞下错误只是介意吹。这段代码是一大堆蠕虫。

在我的网站上有一个正确的示例procedure template that handles errors and transactions,允许嵌入式交易恢复并继​​续错误正确。在错误的情况下您希望处理恢复的典型示例是批处理:当您在批处理中前进时,在每个记录之前保存点然后尝试处理。如果处理失败,则将记录保存在失败的表中,并继续而不会丢失整批

<强>更新

大笑,我也错过了捕获中的提交。然后就像我原来的评论那样糟糕。我仍然更喜欢我的模板,它使用保存点并允许嵌套事务。