天天看點

@@trancount什麼意思(重要)

@@trancount什麼意思

https://www.cnblogs.com/monian/archive/2012/08/24/2654392.html

在處理事務的時候,一般都用RollBack Transaction來復原,但是如果在嵌套事務中這樣使用的話,就會出現錯誤。

在SqlServer裡,嵌套事務的層次是由@@TranCount全局變量反映出來的。每一次Begin Transaction都會引起@@TranCount加1。而每一次Commit Transaction都會使@@TranCount減1,而RollBack Transaction會復原所有的嵌套事務包括已經送出的事務和未送出的事務,而使@@TranCount置0。例如:

Begin Transaction -- @@TranCount = 1

BeginTransaction -- @@TranCount = 2

BeginTransaction -- @@TranCount = 3

Commit Transaction -- @@TranCount = 2

Commit Transaction -- @@TranCount = 1

Commit Transaction -- @@TranCount = 0

如果出現錯誤ROLLBACK TRANSACTION

則:

Begin Transaction -- @@TranCount = 1

BeginTransaction -- @@TranCount = 2

BeginTransaction -- @@TranCount = 3

ROLLBACK TRANSACTION -- @@TranCount = 0

Commit Transaction -- @@TranCount = 0---出現錯誤

Transaction count after EXECUTE indicates that a COMMIT or ROLLBACK TRANSACTION statement is missing. Previous count = 1, current count = 0.

如果被嵌套的事務中發生錯誤,最簡單的方法應該是無論如何都先将它送出,同時傳回錯誤碼(一個正常情況不可能出現的代碼 如 -1)讓上一層事務來處理這個錯誤,進而使@@TranCount 減1。 這樣外層事務在復原或者送出的時候能夠保證外層事務在開始的時候和結束的時候保持一緻。由于裡層事務傳回了錯誤碼,是以外層事務(最外層)可以復原事務,這樣裡面已經送出的事務也可以被復原而不會出現錯誤。

在項目中應該會常常出現這樣的情況,一個存儲過程裡面用了事務,但是不能保證它會被别的帶有事務的存儲過程調用,如果單獨調用的話,出現錯誤可以直接復原,但是如果是被别的帶事務的存儲過程調用的話,RollBack 就會出錯了。是以需要一種機制來區分,建立一個臨時的變量來區分是否嵌套,和嵌套的層數,如下:

DECLARE @TranCounter INT;

SET @TranCounter = @@TRANCOUNT;

IF @TranCounter > 0

SAVE TRANSACTION ProcedureSave;

ELSE

BEGIN TRANSACTION;

…………

--事務内要執行的代碼

…………

IF @@ERROR<>0

goto Error

 Commit Transaction

Commit Transaction

--下面傳回要傳回的值0隻是個例子

Return 0

Error:

IF @TranCounter = 0

ROLLBACK TRANSACTION;

Else

ROLLBACK TRANSACTION ProcedureSave;

Return @Error

SQL Server save transaction

準備:

  create table Nums(X int);

  目的:隻向表中插入一行。

-------------------------------------------------------------------------------------------------------------------------------------

  begin transaction tran_A -- 最好是為事務定義一個名字。

    insert into Nums(X) values(9);

    save transaction save_tran; --定義一個事務的儲存點、當要復原事務時,可以復原到這裡。

    insert into Nums(X) values(4),(3),(2),(1);

    rollback transaction save_tran;--復原事務到儲存點

  commit transaction tran_A;-- 送出事務。

  go

@@trancount什麼意思(重要)