1. 程式人生 > >觸發器中回滾和提交,複製相關

觸發器中回滾和提交,複製相關

在觸發器中回滾和提交

      當執行觸發器時,觸發器的操作好像有一個未完成的事務在起作用。不管激發觸發器的語句在隱式事務中還是顯式事務中,都會這樣。

當語句開始以自動提交模式執行時,如果遇到錯誤,可以通過隱式 BEGIN TRANSACTION 語句恢復該語句生成的所有修改。此隱式事務對批處理中的其他語句沒有影響,因為當語句完成時,此事務要麼提交,要麼回滾。但是,當呼叫觸發器時,此隱式事務仍然有效。

執行觸發器時,將開始隱式事務。如果觸發器執行完後 @@TRANCOUNT 為 0,則會出現錯誤 3609 並終止批處理。由於這個原因,建議避免在觸發器內部使用 ROLLBACK TRANSACTION(它將把 @@TRANCOUNT 重置為 0)以及 COMMIT TRANSACTION(它將把 @@TRANCOUNT 減少為 0)。在回滾後發出 BEGIN TRANSACTION 語句可以阻止錯誤的發生,但這樣可能會導致應用程式邏輯出現問題。

瞭解在觸發器中發出 BEGIN TRANSACTION 語句實際上是開始了一個巢狀事務這一點很重要。在這種情況下,執行 COMMIT TRANSACTION 語句將只應用到巢狀事務。因為回滾巢狀事務時將忽略巢狀的 BEGIN TRANSACTION 語句,所以觸發器中執行的 ROLLBACK TRANSACTION 將回滾過去該觸發器本身發出的所有 BEGIN TRANSACTION 語句。ROLLBACK 回滾到最外部事務並將 @@TRANCOUNT 設定為 0。

在觸發器使用 ROLLBACK TRANSACTION 時,請注意下列行為:

  • 當前事務中該時間點之前所做的所有資料修改都將回滾,包括觸發器所做的修改。
  • 觸發器繼續執行 ROLLBACK 語句之後的所有語句。如果這些語句中的任意語句修改資料,則不回滾這些修改。
  • 觸發器中的 ROLLBACK 關閉並釋放所有在包含激發觸發器的語句的批處理中宣告和開啟的遊標。這包括在激發觸發器的批處理所呼叫的儲存過程中宣告和開啟的遊標。在激發觸發器的批處理之前的批處理中宣告的遊標只關閉。但是,STATIC 或 INSENSITIVE 遊標在下列條件下不會關閉:
    • CURSOR_CLOSE_ON_COMMIT 設定為 OFF。
    • 靜態遊標是同步遊標或者完全填充的非同步遊標。

可以不使用 ROLLBACK TRANSACTION,而使用 SAVE TRANSACTION 語句在觸發器中執行部分回滾。

NOT FOR REPLICATION

      定義一個插入觸發器時設定了 NOT FOR REPLICATION 選項,則所有使用者的插入操作都會觸發該觸發器,但複製代理的插入操作不會觸發該觸發器。