真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

怎么理解.NET可逆框架設(shè)計(jì)

本篇文章為大家展示了怎么理解.NET可逆框架設(shè)計(jì),內(nèi)容簡明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供秦淮網(wǎng)站建設(shè)、秦淮做網(wǎng)站、秦淮網(wǎng)站設(shè)計(jì)、秦淮網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、秦淮企業(yè)網(wǎng)站模板建站服務(wù),10多年秦淮做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

1. 什么是可逆的程序框架

什么叫可逆的?程序的執(zhí)行是可以被無限制回滾的。

什么叫可逆的框架?實(shí)現(xiàn)了對(duì)可逆功能的封裝,并能通過簡單的接口調(diào)用進(jìn)行使用??蚣芸赡苡写笥行?,我想這么稱呼它是為了表達(dá)它的整體性和重要性。

那么到底可逆的需求在哪里?其實(shí)在我們開發(fā)程序的時(shí)候經(jīng)常會(huì)使用事務(wù)來進(jìn)行業(yè)務(wù)的控制。比如刪除訂單,然后刪除訂單明細(xì)等等,對(duì)于這樣的要求很多,我們只能將邏輯控制在一個(gè)事務(wù)范圍內(nèi),不能在沒有事務(wù)性的邏輯代碼中編寫這種要求的業(yè)務(wù)功能。等出現(xiàn)未知錯(cuò)誤的時(shí)候在進(jìn)行事務(wù)的回滾。

你也許會(huì)問,使用原來的事務(wù)處理不是也能進(jìn)行回滾嗎?當(dāng)然不是這么簡單的,我們使用事務(wù)回滾時(shí)只能將資源回滾到最初未進(jìn)行事務(wù)處理前的狀態(tài)。(這里不僅僅指的是數(shù)據(jù)庫事務(wù),而是全局的事務(wù)處理) 我們用圖做個(gè)比較。

傳統(tǒng)的事務(wù)處理圖:

怎么理解.NET可逆框架設(shè)計(jì)

可逆的事務(wù)處理圖:

怎么理解.NET可逆框架設(shè)計(jì)

從這兩幅圖中我們可以很明顯的看出,傳統(tǒng)的事務(wù)處理在事務(wù)處理的過程當(dāng)中無法控制中間數(shù)據(jù),也就是說無法對(duì)事務(wù)處理進(jìn)行分段,然后在進(jìn)行統(tǒng)一的提交或回滾。

在可逆框架的事務(wù)處理里我們就可以控制事務(wù)的執(zhí)行階段,在必要的時(shí)候我們只需提交或者回滾某一階段的數(shù)據(jù)。

1.1環(huán)境事務(wù)

在可逆框架的事務(wù)處理圖中,我們看到事務(wù)的開始,然后就進(jìn)行下一步、下一步這樣的操作。在每進(jìn)行一個(gè)下一步操作的時(shí)候,就是進(jìn)入到了一個(gè)子事務(wù)里處理,在.NET中是可以進(jìn)行事務(wù)的嵌套,其實(shí)也就是依賴事務(wù)Dependent Transaction實(shí)現(xiàn)。通過使用環(huán)境事務(wù)可以讓事務(wù)性感知代碼能自動(dòng)的識(shí)別出您將要使用事務(wù)進(jìn)行操作。所以在每進(jìn)行下一步操作的時(shí)候,只有將當(dāng)前環(huán)境事務(wù)切換為您將依賴的子事務(wù)才行。如果只是單純的使用依賴事務(wù)對(duì)象實(shí)例在使用,那么將無法進(jìn)行諸多其他的事務(wù)處理。

2可逆框架的實(shí)現(xiàn)原理

由于我們只能控制自定義事務(wù)資源管理器的內(nèi)部實(shí)現(xiàn),所以我們?cè)跇?gòu)建自己的數(shù)據(jù)處理時(shí)問題變的簡單多了。

實(shí)現(xiàn)可逆框架的核心技術(shù)就是使用依賴事務(wù)進(jìn)行事務(wù)的克隆操作。將一個(gè)大的事務(wù)處理邏輯上切割成多了小的事務(wù)操作,然后在進(jìn)行統(tǒng)一的提交或回滾。

在實(shí)現(xiàn)上其實(shí)就是將Committable Transaction對(duì)象進(jìn)行包裝,實(shí)現(xiàn)簡單的調(diào)用接口。這里參照了環(huán)境代碼的概念,將對(duì)象的生命周期控制在代碼片段中。

2.1自定義資源管理器的實(shí)現(xiàn)

我們需要擴(kuò)展IEnlistmentNotification接口的實(shí)現(xiàn),加入對(duì)“上一步”、“下一步”的數(shù)據(jù)操作。

請(qǐng)看代碼:

 /***    * author:深度訓(xùn)練    * blog:http://wangqingpei557.blog.51cto.com/    * **/  using System;   using System.Collections.Generic;   using System.Text;   using System.Transactions;     namespace ReversibleLib  {      ///       /// 可逆范圍內(nèi)的資源管理器。      /// 可以使用該類對(duì)易失性資源進(jìn)行事務(wù)范圍內(nèi)的管理。在事務(wù)操作范圍內(nèi)進(jìn)行可逆操作。      ///       /// 需要管理的資源類型      /// 資源在使用、恢復(fù)過程中的數(shù)據(jù)復(fù)制對(duì)象。      public class ReResourceManager : IEnlistmentNotification, IReversibleGetResourceData          where T : class, new()          where Xcopy : class     {          ///           /// 私有字段。資源的持久引用。          ///           T _commitfrontvalue;          ///           /// 私有字段。事務(wù)性操作數(shù)據(jù)對(duì)象。          ///           T _rollbackfrontvalue = new T();          ///           /// 保存數(shù)據(jù)復(fù)制對(duì)象。          ///           Xcopy _copy;          ///           /// 泛型約束需要,內(nèi)部使用。          ///           public ReResourceManager() { }          ///           /// 資源管理器內(nèi)部名稱。便于追蹤          ///           public string Name { get; set; }          ///           /// 重載默認(rèn)構(gòu)造函數(shù),使用資源類型和數(shù)據(jù)復(fù)制對(duì)象初始化資源管理器。          ///           public ReResourceManager(T t, Xcopy icopy)          {              (icopy as IResourceCopy).Copy(_rollbackfrontvalue, t);              _commitfrontvalue = t;              _copy = icopy;          }           #region IEnlistmentNotification 成員          public void Prepare(PreparingEnlistment preparingEnlistment)          {              preparingEnlistment.Prepared();          }          public void Commit(Enlistment enlistment)         {              enlistment.Done();          }          public void InDoubt(Enlistment enlistment)          {              enlistment.Done();          }          public void Rollback(Enlistment enlistment)          {              (_copy as IResourceCopy).Copy(_commitfrontvalue, _rollbackfrontvalue);//回滾事務(wù)              enlistment.Done();          }          #endregion           #region IReversibleGetResourceData 成員          T IReversibleGetResourceData.GetPreviousData()          {              T result = new T();              (_copy as IResourceCopy).Copy(result, _rollbackfrontvalue);              return result;          }          T IReversibleGetResourceData.GetNextData()          {              T result = new T();              (_copy as IResourceCopy).Copy(result, _commitfrontvalue);              return result;          }          #endregion      }  }

2.2可逆框架的入口實(shí)現(xiàn)

我們需要簡單的調(diào)用就能方便的使用可逆功能,不能以一種新的方式使用。所以這里借鑒了Transaction Scope的設(shè)計(jì)思想。

請(qǐng)看代碼:

View Code    /***    * author:深度訓(xùn)練    * blog:http://wangqingpei557.blog.51cto.com/    * **/  using System;   using System.Collections.Generic;   using System.Text;   using System.Transactions;      namespace ReversibleLib   {       ///        /// 使代碼成為可逆框架的事務(wù)性代碼       ///        public class ReversibleManagerScope : IDisposable       {           ///            /// 初始化ReversibleManagerScope新的實(shí)例           ///            public ReversibleManagerScope()           {               ReversibleManager._reversibleManager = new ReversibleManager();           }           ///            /// 使用ReversibleManager對(duì)象構(gòu)造ReversibleManagerScope使用范圍對(duì)象           ///            /// ReversibleManager實(shí)例           public ReversibleManagerScope(ReversibleManager manager)           {               ReversibleManager._reversibleManager = manager;           }           ///            /// 使用自定義資源管理器構(gòu)造ReversibleManagerScope包裝的環(huán)境ReversibleManager.Current中的對(duì)象實(shí)例。           ///            /// IEnlistmentNotification資源管理器           public ReversibleManagerScope(IEnlistmentNotification source)           {               ReversibleManager._reversibleManager = new ReversibleManager(source);           }           ///            /// 全局上下文ReversibleManager對(duì)象銷毀           ///            public void Dispose()           {               ReversibleManager._reversibleManager = null;           }           ///            /// 完成整個(gè)操作的提交。該操作將提交事務(wù)棧中的所有依賴事務(wù)           ///            public void Completed()           {               ReversibleManager.Current.Commit();           }       }       ///        /// 可逆模塊的入口。       /// ReversibleManager對(duì)事務(wù)對(duì)象的封裝,實(shí)現(xiàn)階段性的事務(wù)提交和回滾。       ///        public class ReversibleManager       {           #region 上下文靜態(tài)ReversibleManager實(shí)例           ///            /// 持有對(duì)可逆框架的對(duì)象引用           ///            internal static ReversibleManager _reversibleManager;           ///            /// 獲取當(dāng)前上下文中可逆框架           ///            public static ReversibleManager Current           {               get { return _reversibleManager; }           }           #endregion              #region 構(gòu)造對(duì)象           ///            /// 默認(rèn)構(gòu)造函數(shù)           ///            public ReversibleManager() { }           ///            /// 表示可提交的事務(wù)(主事務(wù))           ///            private CommittableTransaction _commiTransaction;           ///            /// 支持兩階段提交協(xié)議的資源管理器(主資源管理器)           ///            private IEnlistmentNotification _resourceManager;           ///            /// 重載構(gòu)造函數(shù),使用自定義資源管理器構(gòu)造可逆模塊的開始。           ///            /// IEnlistmentNotification接口對(duì)象           public ReversibleManager(IEnlistmentNotification resource)           {               _resourceManager = resource;               InitLoad(IsolationLevel.Serializable);           }           ///            /// 重載構(gòu)造函數(shù),使用自定義資源管理器、內(nèi)部事務(wù)范圍的事務(wù)隔離級(jí)別構(gòu)造可逆模型的開始。           ///            /// IEnlistmentNotification接口對(duì)象           /// IsolationLevel枚舉成員           public ReversibleManager(IEnlistmentNotification resource, IsolationLevel isolationlevel)           {               _resourceManager = resource;               InitLoad(isolationlevel);           }           ///            /// 事務(wù)初始化階段的參數(shù)對(duì)象           ///            TransactionOptions _options;           ///            /// 重載構(gòu)造函數(shù),使用自定義資源管理器、內(nèi)部事務(wù)范圍的事務(wù)隔離級(jí)別、事務(wù)超時(shí)時(shí)間范圍構(gòu)造可逆模塊的開始。           ///            /// IEnlistmentNotification接口對(duì)象           /// IsolationLevel枚舉成員           /// TimeSpan時(shí)間范圍           public ReversibleManager(IEnlistmentNotification resource, IsolationLevel isolationlevel, TimeSpan span)           {               _options = new TransactionOptions();               _options.Timeout = span;               InitLoad(isolationlevel);           }           ///            /// 構(gòu)造CommittableTransaction對(duì)象實(shí)例。           ///            /// 事務(wù)隔離級(jí)別           private void InitLoad(IsolationLevel level)           {               if (_options == null)                   _options = new TransactionOptions();               _options.IsolationLevel = level;               _commiTransaction = new CommittableTransaction(_options);               _commiTransaction.EnlistVolatile(_resourceManager, EnlistmentOptions.None);               //作為事務(wù)棧的頭開始整個(gè)可逆結(jié)構(gòu)。               _tranStack.Push(_commiTransaction);//壓入事務(wù)棧               _resourceStack.Push(_resourceManager);//壓入資源棧               //設(shè)置環(huán)境事務(wù),讓所有支持事務(wù)性感知框架的代碼都能執(zhí)行。               Transaction.Current = _commiTransaction;           }           #endregion              ///            /// 事務(wù)棧,依次存放事務(wù)。           ///            private System.Collections.Generic.Stack _tranStack = new Stack();           ///            /// 資源棧,依次存放事務(wù)使用的資源。           ///            private System.Collections.Generic.Stack _resourceStack = new Stack();           ///            /// 階段性事件委托           ///            /// Transaction環(huán)境事務(wù)           public delegate void PhaseHanlder(System.Transactions.Transaction tran);           ///            /// 下一步事件           ///            public event PhaseHanlder NextEvent;           ///            /// 上一步事件           ///            public event PhaseHanlder PreviousEvent;           ///            /// 開始下一步操作           ///            /// IEnlistmentNotification接口實(shí)現(xiàn)           /// IsolationLevel事務(wù)的隔離級(jí)別(對(duì)全局事務(wù)處理設(shè)置)           /// 下一步操作的自定義數(shù)據(jù)管理器           public void Next(IsolationLevel level, S source)               where S : class,IEnlistmentNotification, new()           {               Transaction tran = _tranStack.Peek();//獲取事務(wù)棧的頂端事務(wù)               if (tran == null)                   tran = Transaction.Current;//主事務(wù)               DependentTransaction depentran = tran.DependentClone(DependentCloneOption.BlockCommitUntilComplete);               //將本次事務(wù)處理的資源管理器壓入資源棧中               depentran.EnlistVolatile(source, EnlistmentOptions.None);               _tranStack.Push(depentran);               _resourceStack.Push(source);               //切換環(huán)境事務(wù)場(chǎng)景               Transaction.Current = depentran;               if (NextEvent != null)                   if (NextEvent.GetInvocationList().Length > 0)                       NextEvent(Transaction.Current);           }           ///            /// 返回上一步操作           ///            /// 需要接受的數(shù)據(jù)對(duì)象類型           /// 需要接受的數(shù)據(jù)對(duì)象引用           public void Previous(out T refadd) where T : class,new()           {               Transaction tran = _tranStack.Pop();               if (tran == null)//頂層事務(wù)                   Transaction.Current.Rollback();               // tran.Rollback();//回滾本事務(wù),將觸發(fā)所有克隆事務(wù)的回滾。               if (PreviousEvent != null)                   if (PreviousEvent.GetInvocationList().Length > 0)                   {                       //設(shè)置上一步數(shù)據(jù)對(duì)象                       refadd = (_resourceStack.Pop() as IReversibleGetResourceData).GetPreviousData();                       PreviousEvent(Transaction.Current);                       return;                   }               refadd = new T();//事務(wù)處理異常           }           ///            /// 提交事物堆棧中的所有事物           ///            public void Commit()           {               if (Transaction.Current is DependentTransaction)                   (Transaction.Current as DependentTransaction).Complete();               for (int i = 0; i < _tranStack.Count - 1; i++)               {                   //依賴事務(wù)                   (_tranStack.Pop() as DependentTransaction).Complete();               }               //提交事務(wù),主事務(wù)。必須進(jìn)行克隆主體的提交才能完成所有階段的操作。               (_tranStack.Pop() as CommittableTransaction).Commit();           }           ///            /// 回滾事物堆棧中的所有事物           ///            public void RollBack()           {               if (Transaction.Current is DependentTransaction)                   (Transaction.Current as DependentTransaction).Rollback();               for (int i = 0; i < _tranStack.Count - 1; i++)               {                   //依賴事務(wù)                   (_tranStack.Pop() as DependentTransaction).Rollback();               }               //提交事務(wù),主事務(wù)。必須進(jìn)行克隆主體的提交才能完成所有階段的操作。               (_tranStack.Pop() as CommittableTransaction).Rollback();           }       }   }

3.示例

這里我使用了一個(gè)簡單的String Builder作為資源管理器需要管理的對(duì)象。

請(qǐng)看代碼:

View Code    /***    * author:深度訓(xùn)練    * blog:http://wangqingpei557.blog.51cto.com/    * **/  using System;   using System.Collections.Generic;   using System.Text;   using System.Data;   using System.Transactions;   using ReversibleLib;      namespace ConsoleApplication1   {       class Program       {           static void Main(string[] args)           {               //構(gòu)造數(shù)據(jù)               StringBuilder strbuilder = new StringBuilder();               strbuilder.Append("0");//初始數(shù)據(jù)為0                  //資源管理器               ReResourceManager strResource =                   new ReResourceManager(strbuilder, new StringBuilderCopy());               strResource.Name = "0資源管理器";               //開始進(jìn)入可逆框架處理環(huán)境               using (ReversibleManagerScope reversible = new ReversibleManagerScope(strResource))               {                   try                  {                       ReversibleManager.Current.PreviousEvent += new ReversibleManager.PhaseHanlder(Current_PreviousEvent);                       ReversibleManager.Current.NextEvent += new ReversibleManager.PhaseHanlder(Current_NextEvent);                       strbuilder.Append("1");//***修改數(shù)據(jù)為01                          //獲取下一步操作的數(shù)據(jù)                       StringBuilder strbuilder2 = (strResource as IReversibleGetResourceData).GetNextData();                       //構(gòu)造下一步操作的自定義資源管理器                       ReResourceManager strResource2 =                           new ReResourceManager(strbuilder2, new StringBuilderCopy());                       strResource2.Name = "2資源管理器";                       ReversibleManager.Current.Next>(                           System.Transactions.IsolationLevel.Serializable, strResource2);                       strbuilder2.Append("2");//第二步修改數(shù)據(jù)為012                          //返回上一步,也就是回滾對(duì)數(shù)據(jù)進(jìn)行“2”設(shè)置的前一個(gè)狀態(tài)                       StringBuilder strbuilder3;                       ReversibleManager.Current.Previous(out strbuilder3);//獲取上一步使用的數(shù)據(jù),這里應(yīng)該是01                          reversible.Completed();//提交所有操作                       Console.WriteLine(strbuilder3);                   }                   catch (Exception err)                   { Console.WriteLine(err.Message); ReversibleManager.Current.RollBack(); }               }               Console.ReadLine();           }              static void Current_NextEvent(Transaction tran)           {               Console.WriteLine("下一步:" + tran.TransactionInformation.LocalIdentifier);               Console.WriteLine("下一步:" + tran.TransactionInformation.DistributedIdentifier);           }           static void Current_PreviousEvent(Transaction tran)           {               Console.WriteLine("上一步:" + tran.TransactionInformation.LocalIdentifier);               Console.WriteLine("上一步:" + tran.TransactionInformation.DistributedIdentifier);           }       }   }

這里我使用0作為資源的初始數(shù)據(jù),然后進(jìn)入到***個(gè)環(huán)節(jié),我將它附加了1,然后進(jìn)入到第二個(gè)環(huán)節(jié),我將它附加了2,這里應(yīng)該是012了,但是下面我突然又返回到了上一步,所以***的數(shù)據(jù)應(yīng)該是01。如果我們需要使用復(fù)雜的數(shù)據(jù)對(duì)象,如常用的Data Table類型,我們一般都是用它來展現(xiàn)一組數(shù)據(jù),然后對(duì)這組數(shù)據(jù)進(jìn)行一系列的操作。

主要是想介紹一下事務(wù)的另一種使用方式,對(duì)可逆框架的設(shè)計(jì)方向算是一個(gè)拋磚引玉吧。

上述內(nèi)容就是怎么理解.NET可逆框架設(shè)計(jì),你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


分享名稱:怎么理解.NET可逆框架設(shè)計(jì)
本文網(wǎng)址:http://weahome.cn/article/jepijs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部