SQL Server TRY...CATCH结构与XACT_STATE的应用

13
我有一个关于 MSDN TRY CATCH 块文档的问题。请查看此文章并向下滚动到示例 C “使用带有 XACT_STATE 的 TRY…CATCH”。

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

示例首先在Try块中放置一个COMMIT TRANSACTION,然后如果XACT_STATE()=1,则在Catch块中放置第二个事务提交语句。
然而,我认为只有在出现错误的情况下Catch块才会执行。那么如何同时执行Catch块和XACT_STATE返回1呢?这似乎是矛盾的。 XACT_STATE文档中有一个未回答的评论,提出了同样的问题。

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


在SO上选择一个答案或提供一个答案会对您的声誉产生长远的影响。 - Sudhanshu Mishra
2个回答

8
我分析如下: 这条评论:

--该表上存在外键约束。

--此语句将生成一个约束违规错误。

是你问题的答案。发生的情况是,当DELETE语句执行时,它会生成一个约束违规错误,并且随后的COMMIT不会执行。事务的XACT_STATE现在为1,CATCH块正在执行。

在顶部,你有

SET XACT_ABORT ON;

这会导致事务状态无法提交,因此此代码块将回滚事务:

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

然而,如果你将"SET XACT_ABORT OFF;"更改为,则会触发CATCH块,尽管事务状态仍然是“可提交的”,因为XACT_STATE = 1

注意:由于约束冲突仍然存在,删除操作仍然无法完成,但你会看到以下输出:

(1 行受影响) 事务可以提交。正在提交事务。


3
XACT_STATE是一个函数,用于返回运行中事务的状态给用户。
XACT_STATE表示请求是否有活动用户事务,以及事务是否能够被提交。
(请记住,通常情况下更新/插入操作出现错误而不是选择查询。) XACT_STATE有三种状态: 1:事务块内的查询是活动和有效的(没有抛出错误)。 0:查询不会抛出错误(例如,在没有更新/插入查询的事务中选择查询)。 -1:事务内部的查询引发了错误(当进入catch块时),并将进行完全回滚(如果我们有4个成功的查询和1个抛出错误,则所有5个查询都将回滚)。
示例:
    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.

    -- 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

参考文献:
https://learn.microsoft.com/en-us/sql/t-sql/functions/xact-state-transact-sql http://www.advancesharp.com/blog/1017/sql-transaction-status-and-xact-state

这些参考文献与IT技术中的事务状态和XACT_STATE有关。请参阅以上链接以获取更多信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接