何爲嵌套事務
簡單解釋:在一個會話中開啓了多個事務
(@@TranCount-------全局參數,用於查看當前會話的事務層數,下文會提到)
例如:
BEGIN TRAN;
----查詢事務層數
SELECT @@TRANCOUNT AS N'事務層數';
INSERT INTO tt( Id, Name, CreateDate ) ----插入1
VALUES ( 1, 'test', GETDATE() );
BEGIN TRAN;
INSERT INTO tt( Id, Name, CreateDate ) ----插入2
VALUES ( 2, 'test', GETDATE() );
----查詢事務層數
SELECT @@TRANCOUNT AS N'事務層數';
可以通過@@TranCount 查到當前會話的事務嵌套層數
一般的使用場景-->多個存儲過程嵌套的時候會出現事務嵌套的情況
要點、特性:
1、在嵌套事務中使用Commit Tran 會按照事務嵌套的層數,依次提交最內存的事務,每提交一次@@TranCount的值-1
(例如上面那個例子,有2層事務,需要2次 Commit Tran 提交才能將數據完全提交給數據庫寫入
並且是依次按照內層事務的順序依次提交,即先提交 '插入2' ,再提交 '插入1')
2、在嵌套事務中使用了回滾操作RollBack Tran ,會導致整個事務完全回滾(不論層數,全部回滾) ,@@TranCount的值重置爲0
所以在存儲過程嵌套的時候,如果子存儲過程報錯,導致事務回滾,會將父存儲過程的事務一併回滾,
導致在父存儲過程中執行rollback tran 或者 commit tran 語句的時候會報錯誤提示
3、可以通過保存事務節點的方式來進行回滾指定的事務節點,而非回滾全部事務
-----保存事務節點1
BEGIN TRAN
SAVE TRAN t1
----查詢事務層數
SELECT @@TRANCOUNT AS N'事務層數'
INSERT INTO dbo.tt
SELECT 246,NEWID(),GETDATE()
-----保存事務節點2
BEGIN TRAN
SAVE TRAN t2
----查詢事務層數
SELECT @@TRANCOUNT AS N'事務層數'
INSERT INTO dbo.tt
SELECT 135,NEWID(),GETDATE()
----回滾指定事務節點
ROLLBACK TRAN t2
----回滾之後將t2事務提交掉
COMMIT TRAN t2
COMMIT TRAN
----查詢表情況
SELECT * FROM dbo.tt
如圖,最終的結果是 外層事務t1中的 246數據被寫入數據庫,而內層事務t2中的 135數據被回滾
(PS:要注意的是當使用 回滾事務指定節點的時候,@@TranCount 是無法被重置爲0/或者減少1的
所以需要在回滾指定節點之後,作一次commit tran 將該事務提交掉)