2012-07-13 147 views
5

INSERT AFTER或UPDATE AFTER觸發器內的回滾是否回滾整個事務或只是作爲觸發原因的當前行,並且是否相同與提交?INSERT AFTER或UPDATE AFTER觸發器內的回滾是否回滾整個事務

我試圖通過我使用MSTDC進行交易的當前項目代碼來檢查它,並且看起來好像完整的交易已被中止。

如果觸發器中的回滾確實回滾了整個事務,是否有解決方法來限制它只是當前行。

我找到了一個鏈接,sybase這一點,但沒有SQL服務器上

+1

Doe SQL Server真的允許在觸發器中使用「回滾」嗎? – 2012-07-13 11:29:02

+0

我想它是這樣的,b'coz我寫了一個,它在執行腳本時並沒有發生任何錯誤,觸發器也在工作。 – Vamsi 2012-07-13 11:32:43

+1

哇。這很可怕 – 2012-07-13 11:33:19

回答

7

是的,它會回滾整個事務。

這一切都在docs(見備註)。請注意我強調的評論 - 這非常重要我會說!

如果ROLLBACK TRANSACTION在觸發器中發出:

在當前事務 這一點所做的所有數據修改都將回滾,包括任何由觸發器進行。

的觸發器繼續 執行ROLLBACK語句之後的任何剩餘語句。如果這些語句中的任何一個修改了數據,則不會回滾 修改。 執行這些剩餘的語句沒有觸發嵌套觸發器。

不會執行觸發 觸發器的語句後的批處理語句。

+1

因此,任何解決方法? – Vamsi 2012-07-13 11:38:51

+4

爲什麼你需要一個解決方法?觸發器就像任何其他代碼一樣 - 你可以隨時控制你想要回滾的地方。 – Jimbo 2012-07-13 12:02:52

+0

我想他所要求的只是回滾調用觸發器的插入/更新語句所涉及的行。要做到這一點,我猜想需要在調用者中設置一個保存點,從觸發器側調用插入/更新,如果需要,根據某些邏輯引發錯誤,然後在調用者中捕獲錯誤並回滾到保存點。儘管我沒有嘗試過。一個更好的設計(例外免費)可能是檢查調用者的條件,甚至不試圖插入/更新這些行。 – crokusek 2014-10-09 17:13:55

0

任何回滾命令都會回滾所有內容,直到@@ trancount爲0,除非您指定了一些保存點並且它不會影響您放置回滾tran命令的位置。

最好的方法是再次查看代碼並確認業務需求並查看爲什麼需要觸發回滾?

1

正如您已經知道的那樣,ROLLBACK命令不可能被修改/調整,以便它只回滾觸發器發出的語句。

如果您確實需要一種方法來「回滾」僅由觸發器執行的操作,則可以採用 作爲解決方法,請考慮修改觸發器,以便在執行操作之前觸發器確保這些操作執行不會產生會導致整個事務回滾的異常情況。例如,如果觸發器插入行,請添加一個檢查以確保新行不違反例如,唯一約束(或外鍵約束),這樣的事情:

IF NOT EXISTS (
    SELECT * 
    FROM TableA 
    WHERE … /* a condition to test if a row or rows you are about 
       to insert aren't going to violate any constraint */ 
) 
BEGIN 
    INSERT INTO TableA … 
END; 

或者,如果觸發刪除行,檢查,如果它不嘗試刪除其它表引用的行(在這種情況下,你通常需要事先知道哪些表威力參考行):

IF NOT EXISTS (
    SELECT * FROM TableB WHERE … 
) 
AND NOT EXISTS (
    SELECT * FROM TableC WHERE … 
) 
AND … 
BEGIN 
    DELETE FROM TableA WHERE … 
END 

同樣,你需要爲update語句檢查,如果有的話。