XACT_ABORT原意是精确终止
其实在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
- (
- 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 行受影响)
- 1
- 2
- 3
- 4
- 5
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' 中插入重复键。
- 1
- 2
- 3
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' 中插入重复键。
- 1
XACT_ABORT=ON有事务机制,错误要回滚事务并停止往下执行,但是不在事务内已经执行的语句还是被成功执行。其实很好理解,和其他地方处理事务一样,把一个事务当成一个语句就好了,错了就回滚并终止执行,是所谓精准终止。