其实在SQL运行中很好理解

默认XACT_ABORT=OFF的情况下,语句不管什么情况,遇到什么错误,反正错误了也继续执行,意思为错也不回头。

在XACT_ABORT=ON的情况下,语句遇到一个错误就停止执行并回滚错误:

关键是这个是事务联系起来,一个事务就是一个错误,所以事务内错了整个事务就回滚,就把一个事务当成一句语句好了。

这个容易和存储过程搞,一个存储过程中可能有好几个事务,如果遇到错误,事务前的还是执行,错误事务本身回滚,但是存储过程不回滚。

如果PB之类的调用存储过程,并且AUTOCOMMIT=TRUE的话,就还后上面分析的一样,如果AUTOCOMMIT=FALSE的话:

1、存储过程没有报错,COMMIT后还是全部执行

2、存储过程报错,ROLLBACK后存储过程所有的操作都回滚


测试:

建立测试表


IF OBJECT_ID ('dbo.a') IS NOT NULL  
DROP TABLE dbo.a  
GO  
CREATE TABLE dbo.a  
    (  
INT NOT NULL,  
CONSTRAINT pk_a PRIMARY KEY (a)  
    )  
GO

1、XACT_ABORT=OFF、无事务



SET XACT_ABORT OFF  
GO  
INSERT INTO a(a) VALUES(1)  
INSERT INTO a(a) VALUES(2)  
INSERT INTO a(a) VALUES(3)  
INSERT INTO a(a) VALUES(3)  
INSERT INTO a(a) VALUES(4)  
INSERT INTO a(a) VALUES(5)  
GO


执行返回:


(1 行受影响)  

  

(1 行受影响)  

  

(1 行受影响)  

消息 2627,级别 14,状态 1,第 4 行  

违反了 PRIMARY KEY 约束 'pk_a'。不能在对象 'dbo.a' 中插入重复键。  

语句已终止。  

  

(1 行受影响)  

  

(1 行受影响)  


结果:

很明显,虽然第四个INSERT处报错了,但是语句还是继续往下执行,直至结束。

2、XACT_ABORT=OFF、有事务


SET XACT_ABORT OFF  
GO  
INSERT INTO a(a) VALUES(1)  
BEGIN TRAN  
INSERT INTO a(a) VALUES(2)  
INSERT INTO a(a) VALUES(3)  
INSERT INTO a(a) VALUES(3)  
INSERT INTO a(a) VALUES(4)  
COMMIT TRAN  
INSERT INTO a(a) VALUES(5)  
GO


返回和结果与1一样,说明报错了以后,只回滚错误语句,同时继续往下执行,直至结束。

XACT_ABORT=OFF没有事务机制,错误就回滚错误语句本身,继续往下一句一句执行,直至结束。


3、XACT_ABORT=ON、无事务


SET XACT_ABORT ON  
GO  
INSERT INTO a(a) VALUES(1)  
INSERT INTO a(a) VALUES(2)  
INSERT INTO a(a) VALUES(3)  
INSERT INTO a(a) VALUES(3)  
INSERT INTO a(a) VALUES(4)  
INSERT INTO a(a) VALUES(5)  
GO


执行返回:




(1 行受影响)  

  

(1 行受影响)  

  

(1 行受影响)  

消息 2627,级别 14,状态 1,第 5 行  

违反了 PRIMARY KEY 约束 'pk_a'。不能在对象 'dbo.a' 中插入重复键。  


结果为:

很明显,虽然也在第四个INSERT出报错了,但是和1的区别是语句停止了执行,下面插入4和5的语句没有被执行。



4、XACT_ABORT=ON、有事务

SET XACT_ABORT ON  
GO  
INSERT INTO a(a) VALUES(1)  
BEGIN TRAN  
INSERT INTO a(a) VALUES(2)  
INSERT INTO a(a) VALUES(3)  
INSERT INTO a(a) VALUES(3)  
INSERT INTO a(a) VALUES(4)  
COMMIT TRAN  
INSERT INTO a(a) VALUES(5)  
GO



执行返回:



(1 行受影响)  

  

(1 行受影响)  

  

(1 行受影响)  

消息 2627,级别 14,状态 1,第 5 行  

违反了 PRIMARY KEY 约束 'pk_a'。不能在对象 'dbo.a' 中插入重复键。  


结果为:

很明显,虽然也在第四个INSERT出报错了,语句停止了执行,但是和3的区别事务内的前两句插入2和3的语句被回滚了,只有不在事务内的插入1的成功了。

XACT_ABORT=ON有事务机制,错误要回滚事务并停止往下执行,但是不在事务内已经执行的语句还是被成功执行。其实很好理解,和其他地方处理事务一样,把一个事务当成一个语句就好了,错了就回滚并终止执行,是所谓精准终止。