[轉帖]XACT_ABORT 的問題

XACT_ABORT原意是精確終止

其實在SQL運行中很好理解

默認XACT_ABORT=OFF的情況下,語句不管什麼情況,遇到什麼錯誤,反正錯誤了也繼續執行,意思爲錯也不回頭。

在XACT_ABORT=ON的情況下,語句遇到一個錯誤就停止執行並回滾錯誤:

關鍵是這個是事務聯繫起來,一個事務就是一個錯誤,所以事務內錯了整個事務就回滾,就把一個事務當成一句語句好了。

這個容易和存儲過程搞,一個存儲過程中可能有好幾個事務,如果遇到錯誤,事務前的還是執行,錯誤事務本身回滾,但是存儲過程不回滾。

如果PB之類的調用存儲過程,並且AUTOCOMMIT=TRUE的話,就還後上面分析的一樣,如果AUTOCOMMIT=FALSE的話:

1、存儲過程沒有報錯,COMMIT後還是全部執行

2、存儲過程報錯,ROLLBACK後存儲過程所有的操作都回滾


測試:

建立測試表

[sql]  view plain  copy
  1. IF OBJECT_ID ('dbo.a'IS NOT NULL  
  2.     DROP TABLE dbo.a  
  3. GO  
  4. CREATE TABLE dbo.a  
  5.     (  
  6.     a INT NOT NULL,  
  7.     CONSTRAINT pk_a PRIMARY KEY (a)  
  8.     )  
  9. GO  

1、XACT_ABORT=OFF、無事務

[sql]  view plain  copy
  1. SET XACT_ABORT OFF  
  2. GO  
  3. INSERT INTO a(a) VALUES(1)  
  4. INSERT INTO a(a) VALUES(2)  
  5. INSERT INTO a(a) VALUES(3)  
  6. INSERT INTO a(a) VALUES(3)  
  7. INSERT INTO a(a) VALUES(4)  
  8. INSERT INTO a(a) VALUES(5)  
  9. GO  
執行返回:

[sql]  view plain  copy
  1. (1 行受影響)  
  2.   
  3. (1 行受影響)  
  4.   
  5. (1 行受影響)  
  6. 消息 2627,級別 14,狀態 1,第 4 行  
  7. 違反了 PRIMARY KEY 約束 'pk_a'。不能在對象 'dbo.a' 中插入重複鍵。  
  8. 語句已終止。  
  9.   
  10. (1 行受影響)  
  11.   
  12. (1 行受影響)  
結果:

[sql]  view plain  copy
  1. 1  
  2. 2  
  3. 3  
  4. 4  
  5. 5  
很明顯,雖然第四個INSERT處報錯了,但是語句還是繼續往下執行,直至結束。

2、XACT_ABORT=OFF、有事務

[sql]  view plain  copy
  1. SET XACT_ABORT OFF  
  2. GO  
  3. INSERT INTO a(a) VALUES(1)  
  4. BEGIN TRAN  
  5. INSERT INTO a(a) VALUES(2)  
  6. INSERT INTO a(a) VALUES(3)  
  7. INSERT INTO a(a) VALUES(3)  
  8. INSERT INTO a(a) VALUES(4)  
  9. COMMIT TRAN  
  10. INSERT INTO a(a) VALUES(5)  
  11. GO  

返回和結果與1一樣,說明報錯了以後,只回滾錯誤語句,同時繼續往下執行,直至結束。

XACT_ABORT=OFF沒有事務機制,錯誤就回滾錯誤語句本身,繼續往下一句一句執行,直至結束。


3、XACT_ABORT=ON、無事務

[sql]  view plain  copy
  1. SET XACT_ABORT ON  
  2. GO  
  3. INSERT INTO a(a) VALUES(1)  
  4. INSERT INTO a(a) VALUES(2)  
  5. INSERT INTO a(a) VALUES(3)  
  6. INSERT INTO a(a) VALUES(3)  
  7. INSERT INTO a(a) VALUES(4)  
  8. INSERT INTO a(a) VALUES(5)  
  9. GO  

執行返回:

[sql]  view plain  copy
  1. (1 行受影響)  
  2.   
  3. (1 行受影響)  
  4.   
  5. (1 行受影響)  
  6. 消息 2627,級別 14,狀態 1,第 5 行  
  7. 違反了 PRIMARY KEY 約束 'pk_a'。不能在對象 'dbo.a' 中插入重複鍵。  
結果爲:

[sql]  view plain  copy
  1. 1  
  2. 2  
  3. 3  
很明顯,雖然也在第四個INSERT出報錯了,但是和1的區別是語句停止了執行,下面插入4和5的語句沒有被執行。

4、XACT_ABORT=ON、有事務

[sql]  view plain  copy
  1. SET XACT_ABORT ON  
  2. GO  
  3. INSERT INTO a(a) VALUES(1)  
  4. BEGIN TRAN  
  5. INSERT INTO a(a) VALUES(2)  
  6. INSERT INTO a(a) VALUES(3)  
  7. INSERT INTO a(a) VALUES(3)  
  8. INSERT INTO a(a) VALUES(4)  
  9. COMMIT TRAN  
  10. INSERT INTO a(a) VALUES(5)  
  11. GO  

執行返回:

[sql]  view plain  copy
  1. (1 行受影響)  
  2.   
  3. (1 行受影響)  
  4.   
  5. (1 行受影響)  
  6. 消息 2627,級別 14,狀態 1,第 5 行  
  7. 違反了 PRIMARY KEY 約束 'pk_a'。不能在對象 'dbo.a' 中插入重複鍵。  
結果爲:

[sql]  view plain  copy
  1. 1  
很明顯,雖然也在第四個INSERT出報錯了,語句停止了執行,但是和3的區別事務內的前兩句插入2和3的語句被回滾了,只有不在事務內的插入1的成功了。

XACT_ABORT=ON有事務機制,錯誤要回滾事務並停止往下執行,但是不在事務內已經執行的語句還是被成功執行。其實很好理解,和其他地方處理事務一樣,把一個事務當成一個語句就好了,錯了就回滾並終止執行,是所謂精準終止。

文章知識點與官方知識檔案匹配,可進一步學習相關知識
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章