XACT_ABORT原意是精确終止
其實在SQL運作中很好了解
預設XACT_ABORT=OFF的情況下,語句不管什麼情況,遇到什麼錯誤,反正錯誤了也繼續執行,意思為錯也不回頭。
在XACT_ABORT=ON的情況下,語句遇到一個錯誤就停止執行并復原錯誤:
關鍵是這個是事務聯系起來,一個事務就是一個錯誤,是以事務内錯了整個事務就復原,就把一個事務當成一句語句好了。
這個容易和存儲過程搞,一個存儲過程中可能有好幾個事務,如果遇到錯誤,事務前的還是執行,錯誤事務本身復原,但是存儲過程不復原。
如果PB之類的調用存儲過程,并且AUTOCOMMIT=TRUE的話,就還後上面分析的一樣,如果AUTOCOMMIT=FALSE的話:
1、存儲過程沒有報錯,COMMIT後還是全部執行
2、存儲過程報錯,ROLLBACK後存儲過程所有的操作都復原
測試:
建立測試表
[sql] view plain copy
- 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、無事務
[sql] view plain copy
- 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
執行傳回:
[sql] view plain copy
- (1 行受影響)
- (1 行受影響)
- (1 行受影響)
- 消息 2627,級别 14,狀态 1,第 4 行
- 違反了 PRIMARY KEY 限制 'pk_a'。不能在對象 'dbo.a' 中插入重複鍵。
- 語句已終止。
- (1 行受影響)
- (1 行受影響)
結果:
[sql] view plain copy
- 1
- 2
- 3
- 4
- 5
很明顯,雖然第四個INSERT處報錯了,但是語句還是繼續往下執行,直至結束。
2、XACT_ABORT=OFF、有事務
[sql] view plain copy
- 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、無事務
[sql] view plain copy
- 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
執行傳回:
[sql] view plain copy
- (1 行受影響)
- (1 行受影響)
- (1 行受影響)
- 消息 2627,級别 14,狀态 1,第 5 行
- 違反了 PRIMARY KEY 限制 'pk_a'。不能在對象 'dbo.a' 中插入重複鍵。
結果為:
[sql] view plain copy
- 1
- 2
- 3
很明顯,雖然也在第四個INSERT出報錯了,但是和1的差別是語句停止了執行,下面插入4和5的語句沒有被執行。
4、XACT_ABORT=ON、有事務
[sql] view plain copy
- 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
執行傳回:
[sql] view plain copy
- (1 行受影響)
- (1 行受影響)
- (1 行受影響)
- 消息 2627,級别 14,狀态 1,第 5 行
- 違反了 PRIMARY KEY 限制 'pk_a'。不能在對象 'dbo.a' 中插入重複鍵。
結果為:
[sql] view plain copy
- 1
很明顯,雖然也在第四個INSERT出報錯了,語句停止了執行,但是和3的差別事務内的前兩句插入2和3的語句被復原了,隻有不在事務内的插入1的成功了。
XACT_ABORT=ON有事務機制,錯誤要復原事務并停止往下執行,但是不在事務内已經執行的語句還是被成功執行。其實很好了解,和其他地方處理事務一樣,把一個事務當成一個語句就好了,錯了就復原并終止執行,是所謂精準終止。