【问题标题】:Why would you commit a transaction within a catch clause?为什么要在 catch 子句中提交事务?
【发布时间】:2010-05-14 17:07:00
【问题描述】:

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

我不明白您为什么要提交导致异常的事务。似乎 10 次中至少有 9 次想要 IF (XACT_STATE()) !=0 ROLLBACK TRANSACTION。您为什么希望在白手起家的情况下取得部分成功?

【问题讨论】:

  • 我试图修剪一些 cmets 以使示例 sql 更短...但是当我尝试编辑代码时 SO 抛出异常。

标签: sql-server-2005 tsql


【解决方案1】:

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

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

更新

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-23
    • 2020-04-19
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    • 2015-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多