T-SQL筆記8_SET XACT_ABORT使用_查檢XACT_ABORT的設定狀態

XACT_ABORT:
指定當 SQL Server 陳述式產生執行階段錯誤時,Transact-SQL 是否自動回復目前的交易。
MS SQL 預設 XACT_ABORT是OFF的

指令語法:
SET XACT_ABORT { ON | OFF }


若在進行資料庫系統開發時遇到一些執行語句
是要做批次(一次多筆)的更新、新增、刪除的時候
往往會透過所謂的「Transaction」 交易進行。
(以 BEGIN TRANSACTION 開頭 COMMIT TRANSACTION結尾,中間包覆的指令即交易行為若遇到異常時,可進行資料 Rollback 。)
但通常交易出現異常時,仍可能導致部分資料寫入資料表中。
此時就可執行此命令,強制約束SQL Server

當 SET XACT_ABORT 被Turn  ON 時,如果 Transact-SQL 陳述式產生執行階段錯誤,就會終止和回復整個交易
當 SET XACT_ABORT 被Turn  OFF 時,在某些情況下,只會回復產生錯誤的 Transact-SQL 陳述式,交易會繼續進行


這裡用一個小測試案例來講解

產生只有一個Column的簡單Table

CREATE TABLE t(P INT UNIQUE)



然後我故意在塞第二筆時候多塞
使其發生中途錯誤

這裡我如果加入SET XACT_ABORT  Off 結果也會一樣
也應證了預設XACT_ABORT是被Turn Off的






如果是SET XACT_ABORT  ON
則會恢復整組交易發生之前狀態(也就是完全沒有塞入半筆)









若要查看目前XACT_ABORT的設定是否有被開啟
則可以使用

指令:
DBCC USEROPTIONS
傳回目前連接在使用中 (已設定) 的 SET 選項。

若是有設定Turn On就會顯示在此結果集當中。






這樣看起來感覺好像我只要開頭把它開起來就好了
幹嘛還要自己寫ROLLBACK語句呢?


再來看一個案例
產生員工薪資表、員工功號表,功號為主鍵(只能唯一)
這裡故意塞重複工號在交易執行過程中




此時若我改成TURN OFF則會變成如此結果
你可以看到在turn off後若要避免資料誤入就必須將roll back寫在CATCH Exception區塊
事實上若沒有多加那段 if  @@trancount > 0 就rollback就進DB了

此外此問題也有人在Stackoverflow上發問
回答人分享
事實上SQL Server Try catch 方式在rollback 仍有風險
因為try catch 並非100% 能抓到所有例外
https://stackoverflow.com/questions/21030099/are-these-code-snippets-equivalent-set-xact-abort-on-vs-try-catch-rollback

A TRY…CATCH construct catches all execution errors that have a severity higher than 10 that do not close the database connection.

So, try catch does not catch all possible errors. You can use xact_abort on in addition to try catch.

try/catch give you more flexibility, i.e., you are not limited to just a rollback when something is not happy.






Reference:

BEGIN TRAN with XACT_ABORT
http://sharedderrick.blogspot.com/2018/11/begin-tran-with-xactabort.html
[SQL Server]Talking about XACT_ABORT
https://dotblogs.com.tw/ricochen/2018/01/21/034210
SQL Server - 交易控制 - XACT_ABORT
http://caryhsu.blogspot.com/2011/01/sql-server-xactabort.html
How Does XACT_ABORT Work In SQL
https://www.c-sharpcorner.com/uploadfile/suba.venkat/how-does-xactabort-work-in-sql/


留言

這個網誌中的熱門文章

何謂淨重(Net Weight)、皮重(Tare Weight)與毛重(Gross Weight)

Architecture(架構) 和 Framework(框架) 有何不同?_軟體設計前的事前規劃的藍圖概念

經得起原始碼資安弱點掃描的程式設計習慣培養(五)_Missing HSTS Header