T-SQL事务遇到错误,但未取消

时间:2018-07-29 22:15:26

标签: sql sql-server database tsql transactions

根据定义,如果其中的任何语句导致错误,则应取消T-SQL事务。但是,我偶然发现事务通过并在其中途发生错误的情况。

示例环境设置:

--test tables:
IF OBJECT_ID('t2', 'U') IS NOT NULL  
    DROP TABLE t2;  
GO      
IF OBJECT_ID('t1', 'U') IS NOT NULL  
    DROP TABLE t1;  
GO     

CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY);  
CREATE TABLE t2  (a INT NOT NULL REFERENCES t1(a));  
GO      

INSERT INTO t1 
VALUES (1), (3), (4), (6);  
GO  

交易测试:

BEGIN TRANSACTION
     INSERT INTO t2 VALUES (1); 
     INSERT INTO t2 VALUES (2); -- Foreign key error will be thrown.  
     INSERT INTO t2 VALUES (3);  

COMMIT TRANSACTION;  

这应该是由于外键错误而取消的,但不是:

SELECT * FROM t2;

返回两行的结果-值1和3。

添加SET XACT_ABORT ON可以完成这项工作,但是当中间出现错误时,整个交易怎么可能停滞不前?

1 个答案:

答案 0 :(得分:2)

根据特定的错误,在没有XACT_ABORT ON的错误之后,T-SQL批处理将继续。我建议在TRY/CATCH中加上IF @@TRANCOUNT > 0 ROLLBACK;CATCH BLOCK中的XACT_ABORT ON以确保在查询取消或客户端超时的情况下立即回滚(这可以防止{{1 }}阻止执行):

CATCH