Sql-Server
當 XACT_ABORT 開啟時,TRY CATCH 塊的意義何在?
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;
始終是必要的,以便正確回滾事務。在觸發器中,您絕不能顯式回滾。如果這樣做,您將收到一個虛假錯誤 #3609
The transaction ended in the trigger. The batch has been aborted.
並且預設XACT_ABORT
情況ON
下在觸發器中。但有時您確實想在 SQL 程式碼中擷取和處理錯誤。為此,您必須使用
BEGIN TRY
BEGIN CATCH
,並且還必須使用ROLLBACK
如圖所示的條件。例如,您可以在這個 fiddle中看到,事務之外的第二個插入仍然被送出,即使
XACT_ABORT
wasON
,因為BEGIN CATCH
使用了。TL;博士; 如果處理錯誤,
您只需要使用
BEGIN CATCH
和條件。如果您有一個顯式事務,無論是否有 ,都必須始終如此,以確保回滾正確發生。ROLLBACK;
SET XACT_ABORT``ON``CATCH