亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C#綜合揭秘——細說事務(下)

發布時間:2020-04-11 11:16:23 來源:網絡 閱讀:808 作者:leslies2 欄目:編程語言

目錄

一、事務的定義

二、事務管理器

三、在ADO.NET中實現事務

四、隱式事務 TransactionScope

五、在WCF中實現事務

六、嵌套式事務

七、異步事務

六、嵌套式事務

嵌套式事務經常會出現在項目中,但往往容易被大家忽略,下面介紹一下 嵌套式事務的用法:

 1 using (TransactionScope scope1 = new TransactionScope())            
 2 {
 3        ..............               
 4        using (TransactionScope scope2=new TransactionScope(TransactionScopeOption.RequiresNew))
 5        {
 6               ..............
 7               scope2.Complete();   //只完成嵌套式的內部事務,但事務并未正式提交
8 } 9 scope1.Complete(); //代表完成所有事務,事務正式提交
10 }

一 般項目中,大家都只會把事務用在DAL層,用于管理數據的CRUD,但其實在一些操作中,某些數據的操作必須具有一致性。比如在訂單管理中,當插入一條 OrderItem時,Order表內的總體價格,商品數量等也會隨之改變。很多人把兩個表的操作合成一個方法,放在OrderDAL中完成。但其實這樣 做違返設計的原則,因為計算Order的總體價格時可能會包含商品優惠、客戶等級、客戶積分等等業務邏輯,而在DAL層不應該包含任何的業務邏輯存在的, 所以這樣操作應該放在業務層完成。這時候,業務層的方法內就需要同時調用OrderItemDAL的AddOrderItem(OrderItem) 方法和OrderDAL的UpdateOrder(Order)方法,為了保證數據的一致性更新,就需要使用嵌套式事務。但這往往容易被開發人員所忽略, 當Order表的更新成功而OrderItem表的插入失敗時,系統不能保證數據的同步回滾,那就會造成數據的邏輯性錯誤。

下面的例子就是為了保證數據一致性更新而使用的嵌套式事務,在使用嵌套式事務的時候要應該注意及其把對象釋放,避免做成死鎖

 1 namespace DAL
 2 {     
 3      public class OrderDAL
 4      {
 5          public void UpdateOrder(Order order)
 6          {
 7              using (TransactionScope scope = new TransactionScope())
 8              {
 9                   ......         
10                   scope.Complete();
11              }
12          }
13      }
14  
15      public class OrderItemDAL
16      {
17          public void AddOrderItem(OrderItem orderItem)
18          {
19              using (TransactionScope scope = new TransactionScope())
20              {
21                  ......
22                  scope.Complete();
23              }
24          }
25      }
26  }
27 
28 namespace BLL
29 {
30      public class OrderManager
31      {
32          public void AddOrderItem(OrderItem item)
33          {
34              using (TransactionScope scope = new TransactionScope())
35              {
36                  OrderItemDAL orderItemDAL=new OrderItemDAL();
37                  orderItemDAL.AddOrderItem(item);
38                  OrderDAL orderDAL=new OrderDAL();
39                  ........
40                  orderDAL.UpdateOrder(order);
41                  scope.Complete();
42              }
43          }
44      }
45 }

回到目錄

 

七、異步事務

記得在第二節的時候曾經提起過事務類Transaction的方法中包含方法

public DependentTransaction DependentClone(DependentCloneOption)

此方法作用是克隆當前的事務,它在多線程調用同一事務的情況下使用經常使用。其中DependentCloneOption包含有兩個選項:

一為BlockCommitUntilComplete,這表示在依賴事務未完成前,事務將處于阻塞狀態,只有在所有依賴事務完成后,事務才能執行提交;

二為RollbackInNotComplete,這表示依賴事務必須在事務完成前調用Complete(),否則事務會被視為失敗。

 

在 普通情況下,事務都會通過Transaction.Current 來獲取,但此方法只能獲取當前線程下的事務對象,在異步方法當中,這只會返回一個空值 null 。此時就需要使用DependentClone 方法獲取依賴事務對象 DependentTransaction ,再把此對象作為參數傳遞到回調函數中。

 1      class Program
 2      {
 3          static void Main(string[] args)
 4          {
 5              Method();
 6              Console.ReadKey();
 7          }
 8  
 9          static void Method()
10          {
11              using (TransactionScope scope = new TransactionScope())
12              {
13                  ShowMessage("Main Thread");
14  
15                  //獲取一個依賴事務,把依賴事務作為回調參數傳到回調函數中
16 DependentTransaction dependentTransaction= 17 Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete); 18 ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncThread), dependentTransaction); 19 ........ 20 scope.Complete(); //完成主線程事務,在依賴事務完成前,事務提交將處于阻塞狀態 21 } 22 } 23 24 static void AsyncThread(object transaction) 25 { 26 //獲取依賴事務,利用TransactionScope(Transaction)構造函數生成隱式事務
27 DependentTransaction dependentTransaction = (DependentTransaction)transaction; 28 using (TransactionScope scope = new TransactionScope(dependentTransaction)) 29 { 30 ShowMessage("AsyncThread"); 31 .......... 32 scope.Complete(); //完成異步事務
33 } 34 //完成依賴事務
35 dependentTransaction.Complete(); 36 } 37 38 static void ShowMessage(string data) 39 { 40 if (Transaction.Current != null) 41 { 42 Transaction transaction = Transaction.Current; 43 string info = string.Format("{0}:{1}\nTransaction:\n DistributedIndentifier:{2} \n LocalIndentifier:{3}\n", 44 data,Thread.CurrentThread.ManagedThreadId.ToString(), 45 transaction.TransactionInformation.DistributedIdentifier, 46 transaction.TransactionInformation.LocalIdentifier); 47 Console.WriteLine(info); 48 } 49 } 50 }

首 先在主線程中利用 Transaction.DependentClone(DependentCloneOption.BlockCommitUntilComplete) 方法生成一個依賴事務,注意方法使用了BlockCommitUntilComplete的方式生成,即事務將在所有依賴事務使用Complete()后 才能執行提交。

然后利用ThreadPool.QueueUserWorkItem(WaitCallback,Object)方法把依賴事務作為回調參數傳遞到回調函數中。

最后在回調函數中使用TransactionScope(transaction)構造函數生成對象,這代表把參數transaction作為當前的環境事務對象。觀察下面的運行結果,兩個線程中的事務都是同一個事務。

C#綜合揭秘——細說事務(下)

結束語

事務是在多個層次都會使用到的,但很多項目當中往往會忽略了這一點而只在數據層使用,在大型的系統當中這樣可能會影響到系統的一致性。特別是在分布式系統當中,操作往往同時存在于多個不同的系統當中,事務的處理更顯示出其重要性。

希望本篇文章對相關的開發人員有所幫助。對JAVA與.NET開發有興趣的朋友歡迎加入QQ群:162338858 C#綜合揭秘——細說事務(下)

回到目錄

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

紫金县| 商都县| 华安县| 石景山区| 商城县| 荣成市| 衡阳县| 嵊州市| 宝山区| 英吉沙县| 伊吾县| 紫金县| 会昌县| 苏尼特左旗| 黑山县| 涞源县| 双牌县| 灵石县| 洛隆县| 响水县| 陆丰市| 晋城| 临泽县| 鱼台县| 汪清县| 深泽县| 婺源县| 休宁县| 武功县| 开阳县| 镇原县| 海原县| 波密县| 大安市| 柳林县| 永平县| 巫山县| 德江县| 寿光市| 邯郸县| 珠海市|