Dot-Net

嵌套/子 TransactionScope 回滾

  • April 30, 2010

我正在嘗試嵌套 TransactionScopes (.net 4.0),就像在 SQL Server 中嵌套事務一樣,但是看起來它們的操作方式不同。我希望我的子事務能夠在失敗時回滾,但允許父事務決定是否送出/回滾整個操作。問題是當第一次完成時,事務被回滾。我意識到完成與送出是不同的。

我正在嘗試做的一個非常簡化的範例:

static void Main(string[] args)
{
   using(var scope = new TransactionScope()) // Trn A
   {
       // Insert Data A

       DoWork(true);
       DoWork(false);

       // Rollback or Commit
   }
}

// This class is a few layers down
static void DoWork(bool fail)
{
   using(var scope = new TransactionScope()) // Trn B
   {
       // Update Data A

       if(!fail)
       {
           scope.Complete();
       }
   }
}

我不能使用 Suppress 或 RequiresNew 選項,因為 Trn B 依賴於 Trn A 插入的數據。如果我使用這些選項,Trn B 會被 Trn A 阻止。

有什麼想法可以讓它工作,或者是否可以使用 System.Transactions 命名空間?

謝謝

你可能不會喜歡這個答案,但是……

在嵌套範圍內投票

雖然嵌套作用域可以加入根作用域的環境事務,但在嵌套作用域中呼叫Complete對根作用域沒有影響。只有從根作用域到最後一個嵌套作用域的所有作用域都投票送出事務,才會送出事務。

(來自使用事務範圍實現隱式事務

不幸的是,TransactionScope該類沒有提供任何用於隔離工作單元的機制(據我所知)。要麼全有,要麼全無。您可以使用 防止任何事務在特定工作單元上發生TransactionScopeOption.Suppress,但這可能不是您想要的,因為您將失去該範圍內的任何內容的原子性。

當您使用TransactionScope. 一旦 aTransactionScope在沒有執行的情況下被處理或收集Complete,整個環境事務就會回滾;就這樣,遊戲結束。

事實上,SQL Server 根本不支持真正的嵌套事務,儘管通過SAVE TRAN適當使用語句可以獲得相同的最終結果(儘管有些不直覺) 。如果您需要此特定行為,則將此邏輯重新實現為儲存過程(或其中幾個)可能是您的最佳選擇。

引用自:https://stackoverflow.com/questions/2741988