SQL Server TRY...CATCH with XACT_STATE



我有一个关于TRY CATCH块的MSDN文档的问题。查看这篇文章并向下滚动到示例C"使用TRY…CATCH with XACT_STATE"

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

该示例首先将COMMIT TRANSACTION放在Try块中,然后将第二个XACT_STATE()=1放在Catch块中。

然而,我认为Catch块只会在出现错误的情况下执行。那么,Catch块如何执行而XACT_STATE返回1呢?这似乎很矛盾。

XACT_STATE文档中有一个未回答的注释,它问了同样的问题

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

@user1181412分析如下:注释:

——表中存在一个FOREIGN KEY约束。

——该语句将生成约束违反错误

是你问题的答案。实际情况是,当执行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行)受影响)事务是可提交的。提交事务。

XACT_STATE是一个向用户返回正在运行的事务状态的函数。
XACT_STATE表示请求是否有活动的用户事务,以及该事务是否能够提交。

(请记住,错误通常发生在update/insert而不是update/insert上)选择查询)。


XACT_STATE有3种状态:

1: Transaction块内的查询是活动且有效的(没有抛出错误)。
0:查询不会抛出错误(例如,在没有更新/插入查询的事务中执行select查询)。
-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-sqlhttp://www.advancesharp.com/blog/1017/sql-transaction-status-and-xact-state

最新更新