Sql-Server

儲存過程出錯時,為什麼要送出部分事務?

  • April 26, 2021

我有一個儲存過程,它首先聲明一些變數,然後包含begin tran;在此之後,它對提供的參數執行一些驗證(並且每次提供的參數驗證失敗時都會增加一個錯誤計數)。如果沒有錯誤計數,則繼續執行 7 次插入。在此之後,它有commit tran;

最近我在列表中添加了第 8 個插入。隱式類型轉換意味著如果插入某些插入的數據將被截斷。這向 SSMS 螢幕拋出了一個錯誤,但我發現前 7 個插入已送出,而第 8 個顯然沒有完成。

我很感激我可以包含一個try ... catch塊來處理錯誤,但是如果一個顯式begin tran;不能使整個工作塊自治到commit,那麼有什麼意義呢?我錯過了什麼?

我知道我也許可以將我的程序呼叫包含在該級別的事務中 - 但是有人可以解釋發生了什麼以及為什麼begin tran當包含在程序主體中時似乎不受尊重?如果呼叫該過程開始一個隱式事務,那麼 proc 中的錯誤步驟是否不應該回滾由 proc 影響的所有更改 - 即使沒有明確包括begin tran在 proc 主體中?

事務不會在錯誤時自動回滾——這不是它們的設計目的。它們旨在使您能夠回滾。但是,您仍然需要做一些事情來實現這一點。

正如您所提到的,您可以通過 實現這一點TRY...CATCH,這使您可以最大程度地控制是否以及如何回滾。

聽起來您期待 的行為SET XACT_ABORT ON,您可以在儲存過程中設置它,但這不是預設行為。文件中設置XACT_ABORTon vs off的描述是:

當 SET XACT_ABORT 為 ON 時,如果 Transact-SQL 語句引發執行時錯誤,則整個事務將終止並回滾。

當 SET XACT_ABORT 為 OFF 時,在某些情況下,只有引發錯誤的 Transact-SQL 語句被回滾並且事務繼續處理。根據錯誤的嚴重程度,即使 SET XACT_ABORT 為 OFF,也可能回滾整個事務。OFF 是 T-SQL 語句中的預設設置,而 ON 是觸發器中的預設設置。


SET XACT_ABORT什麼時候ON,呼叫故障過程會在 SSMS 中返回消息,例如:

Msg 8152, Level 16, State 14, Procedure spProcName, Line 298 [Batch Start Line 5]
String or binary data would be truncated.

Completion time: 2021-04-26T10:51:00.8420902+10:00

SSMS 中的第一行是紅色的。

SET XACT_ABORTis時OFF,呼叫故障過程包括一條附加消息:

Msg 8152, Level 16, State 14, Procedure spProcName, Line 298 [Batch Start Line 5]
String or binary data would be truncated.
The statement has been terminated.

Completion time: 2021-04-26T10:53:52.5951780+10:00

特別是,當您看到以下消息時,這意味著過程中錯誤語句之前的語句已被送出:

The statement has been terminated.

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