Sqlserver——異常總結——關於嵌套事務

何爲嵌套事務

簡單解釋:在一個會話中開啓了多個事務

(@@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 將該事務提交掉)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章