溫馨提示×

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

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

C#綜合揭秘——細(xì)說(shuō)事務(wù)(下)

發(fā)布時(shí)間:2020-04-11 11:16:23 來(lái)源:網(wǎng)絡(luò) 閱讀:799 作者:leslies2 欄目:編程語(yǔ)言

目錄

一、事務(wù)的定義

二、事務(wù)管理器

三、在ADO.NET中實(shí)現(xiàn)事務(wù)

四、隱式事務(wù) TransactionScope

五、在WCF中實(shí)現(xiàn)事務(wù)

六、嵌套式事務(wù)

七、異步事務(wù)

六、嵌套式事務(wù)

嵌套式事務(wù)經(jīng)常會(huì)出現(xiàn)在項(xiàng)目中,但往往容易被大家忽略,下面介紹一下 嵌套式事務(wù)的用法:

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

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

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

 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 }

回到目錄

 

七、異步事務(wù)

記得在第二節(jié)的時(shí)候曾經(jīng)提起過(guò)事務(wù)類(lèi)Transaction的方法中包含方法

public DependentTransaction DependentClone(DependentCloneOption)

此方法作用是克隆當(dāng)前的事務(wù),它在多線(xiàn)程調(diào)用同一事務(wù)的情況下使用經(jīng)常使用。其中DependentCloneOption包含有兩個(gè)選項(xiàng):

一為BlockCommitUntilComplete,這表示在依賴(lài)事務(wù)未完成前,事務(wù)將處于阻塞狀態(tài),只有在所有依賴(lài)事務(wù)完成后,事務(wù)才能執(zhí)行提交;

二為RollbackInNotComplete,這表示依賴(lài)事務(wù)必須在事務(wù)完成前調(diào)用Complete(),否則事務(wù)會(huì)被視為失敗。

 

在 普通情況下,事務(wù)都會(huì)通過(guò)Transaction.Current 來(lái)獲取,但此方法只能獲取當(dāng)前線(xiàn)程下的事務(wù)對(duì)象,在異步方法當(dāng)中,這只會(huì)返回一個(gè)空值 null 。此時(shí)就需要使用DependentClone 方法獲取依賴(lài)事務(wù)對(duì)象 DependentTransaction ,再把此對(duì)象作為參數(shù)傳遞到回調(diào)函數(shù)中。

 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                  //獲取一個(gè)依賴(lài)事務(wù),把依賴(lài)事務(wù)作為回調(diào)參數(shù)傳到回調(diào)函數(shù)中
16 DependentTransaction dependentTransaction= 17 Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete); 18 ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncThread), dependentTransaction); 19 ........ 20 scope.Complete(); //完成主線(xiàn)程事務(wù),在依賴(lài)事務(wù)完成前,事務(wù)提交將處于阻塞狀態(tài) 21 } 22 } 23 24 static void AsyncThread(object transaction) 25 { 26 //獲取依賴(lài)事務(wù),利用TransactionScope(Transaction)構(gòu)造函數(shù)生成隱式事務(wù)
27 DependentTransaction dependentTransaction = (DependentTransaction)transaction; 28 using (TransactionScope scope = new TransactionScope(dependentTransaction)) 29 { 30 ShowMessage("AsyncThread"); 31 .......... 32 scope.Complete(); //完成異步事務(wù)
33 } 34 //完成依賴(lài)事務(wù)
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 }

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

然后利用ThreadPool.QueueUserWorkItem(WaitCallback,Object)方法把依賴(lài)事務(wù)作為回調(diào)參數(shù)傳遞到回調(diào)函數(shù)中。

最后在回調(diào)函數(shù)中使用TransactionScope(transaction)構(gòu)造函數(shù)生成對(duì)象,這代表把參數(shù)transaction作為當(dāng)前的環(huán)境事務(wù)對(duì)象。觀察下面的運(yùn)行結(jié)果,兩個(gè)線(xiàn)程中的事務(wù)都是同一個(gè)事務(wù)。

C#綜合揭秘——細(xì)說(shuō)事務(wù)(下)

結(jié)束語(yǔ)

事務(wù)是在多個(gè)層次都會(huì)使用到的,但很多項(xiàng)目當(dāng)中往往會(huì)忽略了這一點(diǎn)而只在數(shù)據(jù)層使用,在大型的系統(tǒng)當(dāng)中這樣可能會(huì)影響到系統(tǒng)的一致性。特別是在分布式系統(tǒng)當(dāng)中,操作往往同時(shí)存在于多個(gè)不同的系統(tǒng)當(dāng)中,事務(wù)的處理更顯示出其重要性。

希望本篇文章對(duì)相關(guān)的開(kāi)發(fā)人員有所幫助。對(duì)JAVA與.NET開(kāi)發(fā)有興趣的朋友歡迎加入QQ群:162338858 C#綜合揭秘——細(xì)說(shuō)事務(wù)(下)

回到目錄

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI