1、TransactionScope 環境事務框架
1 static async Task TransactionScopeAsync() 2 { 3 using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) 4 { 5 Transaction.Current.TransactionCompleted += OnTransactionCompleted; 6 7 Utilities.DisplayTransactionInformation("Ambient TX created", 8 Transaction.Current.TransactionInformation); 9 10 var s1 = new Student 11 { 12 FirstName = "Angela", 13 LastName = "Nagel", 14 Company = "Kantine M101" 15 }; 16 var db = new StudentData(); 17 await db.AddStudentAsync(s1); 18 19 if (!Utilities.AbortTx()) 20 scope.Complete(); 21 else 22 Console.WriteLine("transaction will be aborted"); 23 24 } // scope.Dispose() 25 26 }
2、嵌套事務異步
1 static void NestedScopes() 2 { 3 using (var scope = new TransactionScope()) 4 { 5 Transaction.Current.TransactionCompleted += OnTransactionCompleted; 6 7 Utilities.DisplayTransactionInformation("Ambient TX created", 8 Transaction.Current.TransactionInformation); 9 10 using (var scope2 = 11 new TransactionScope(TransactionScopeOption.RequiresNew)) 12 { 13 Transaction.Current.TransactionCompleted += OnTransactionCompleted; 14 15 Utilities.DisplayTransactionInformation( 16 "Inner Transaction Scope", 17 Transaction.Current.TransactionInformation); 18 19 scope2.Complete(); 20 } 21 scope.Complete(); 22 } 23 24 }
事務完成代碼async
1 static void OnTransactionCompleted(object sender, TransactionEventArgs e) 2 { 3 Utilities.DisplayTransactionInformation("TX completed", 4 e.Transaction.TransactionInformation); 5 }
你可能不知道這一點,在 .NET Framework 4.5.0 版本中包含有一個關於 System.Transactions.TransactionScope 在與 async/await 一塊兒工做時會產生的一個嚴重的 bug 。因爲這個錯誤,TransactionScope 不能在異步代碼中正常操做,它可能更改事務的線程上下文,致使在處理事務做用域時拋出異常。函數
這是一個很大的問題,由於它使得涉及事務的異步代碼極易出錯。ui
好消息是,在 .NET Framework 4.5.1 版本中,微軟發佈了這個 "異步鏈接" 錯誤的修復程序。做爲開發者的咱們須要明確的作到如下兩點:spa
TransactionScopeAsyncFlowOption.Enabled .
在 .NET 4.5.1中,TransactionScope 有一個名爲 TransactionScopeAsyncFlowOption 的新枚舉,能夠在構造函數中提供。 您必須經過指定,明確地選擇跨線程連續的事務流,以下:線程
1 using (var tx = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) 2 { 3 await SomeMethodInTheCallStackAsync() 4 .ConfigureAwait(false); 5 6 tx.Complete(); 7 }
你可能很好奇,默認的 TransactionScopeAsyncFlowOption 是 Suppress(阻止的),由於微軟想避免破壞 .NET 4.5.0 版本中代碼庫中行爲。code
使用 TransactionScope 結合 async / await 時,你應該更新全部使用 TransactionScope 的代碼路徑以啓用 TransactionScopeAsyncFlowOption.Enabled 。 這樣才能使事務可以正確地流入異步代碼,防止在TransactionScope下使用時業務邏輯不正常。orm