Sql-Server

當 XACT_ABORT 開啟時,TRY CATCH 塊的意義何在?

  • March 25, 2022

XACT_ABORT_ON 的程式碼範例:

SET XACT_ABORT_ON;

BEGIN TRY
 BEGIN TRANSACTION
   //do multiple lines of sql here
 COMMIT TRANSACTION
END TRY

BEGIN CATCH
 IF (@@TRANCOUNT > 0) ROLLBACK;
 //may be print/log/throw error
END CATCH

由於 XACT ABORT 為 ON,任何錯誤都會自動回滾事務。那麼 TRY CATCH 塊有什麼作用呢?

您是對的,沒有必要擷取您不打算處理的錯誤。SET XACT_ABORT ON;確保在所有情況下都回滾(除了一些非常奇怪的無法擷取錯誤的邊緣情況,Erland Sommarskog 說這些基本上是未修復的錯誤)。來自動態 SQL 的語法錯誤也不會被擷取和回滾,但這只是使用好的 IDE、適當的版本控制和避免使用動態 SQL 的另一個很好的理由。

CATCH在我看來,只有當你打算處理它們時才需要出錯。Erland 的文章通常被誤解,它們旨在處理錯誤,而不僅僅是擷取和重新拋出。

SET XACT_ABORT ON;始終是必要的,以便正確回滾事務。

在觸發器中,您絕不能顯式回滾。如果這樣做,您將收到一個虛假錯誤 #3609The transaction ended in the trigger. The batch has been aborted.並且預設XACT_ABORT情況ON下在觸發器中。


但有時您確實想在 SQL 程式碼中擷取和處理錯誤。為此,您必須使用BEGIN TRY BEGIN CATCH,並且還必須使用ROLLBACK如圖所示的條件。

例如,您可以在這個 fiddle中看到,事務之外的第二個插入仍然被送出,即使XACT_ABORTwas ON,因為BEGIN CATCH使用了。


TL;博士; 如果處理錯誤,

您只需要使用BEGIN CATCH和條件。如果您有一個顯式事務,無論是否有 ,都必須始終如此,以確保回滾正確發生。ROLLBACK;

SET XACT_ABORT``ON``CATCH

引用自:https://dba.stackexchange.com/questions/306846