using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using System.Transactions; namespace ConsoleApplication4 { /*代码1:资源管理器*/ public class IEnlistmentNotificationDemo<T, Xcopy> : IEnlistmentNotification where T : new() where Xcopy : class { T _commitfrontvalue; T _rollbackfrontvalue = new T(); Xcopy copy; public IEnlistmentNotificationDemo(T t, Xcopy icopy) { //定义一个恢复接口 (icopy as IResourceCopy<T>).Copy(_rollbackfrontvalue, t); _commitfrontvalue = t;//保持对资源修改的引用 copy = icopy; } #region IEnlistmentNotification 成员 public void Prepare(PreparingEnlistment preparingEnlistment) { //两阶段提交协议中的准备阶段 Console.WriteLine("准备提交"); string key = Console.ReadLine(); if (key== "Y" || key == "y") { preparingEnlistment.Prepared(); //投票提交事务 } else if (key == "N" || key == "n") { Console.WriteLine(" 由我投票整个事务回滚:" + _rollbackfrontvalue); (copy as IResourceCopy<T>).Copy(_commitfrontvalue, _rollbackfrontvalue);//回滚事务自愿 preparingEnlistment.ForceRollback();//投票回滚事务,资源管理发生错误时因该将其自动回复数据, //因为事务管理不会通知发生ForceRollback()方法的管理器。 } } public void Commit(Enlistment enlistment) { //尝试提交 Console.WriteLine("事务尝试提交"); enlistment.Done();//通知事务管理器,参与者已完成提交工作。 } public void Rollback(Enlistment enlistment) { //事务激活阶段处理错误,执行回滚 Console.WriteLine("操作失败,回滚" + _rollbackfrontvalue); (copy as IResourceCopy<T>).Copy(_commitfrontvalue, _rollbackfrontvalue);//回滚事务自愿 enlistment.Done(); } public void InDoubt(Enlistment enlistment) { //与其他的资源管理器失去联系 Console.WriteLine("与其他的资源管理器失去联系,通常记录日志"); enlistment.Done(); } #endregion } //代码2:资源复制接口 /// <summary> /// 事务性资源管理器中的资源拷贝,不同的资源类型存在多种拷贝形式。 /// </summary> public interface IResourceCopy<T> { void Copy(T t1, T t2); } //代码3:实现StringBuilder类型的数据复制 /// <summary> /// StringBuilder类型的数据Copy对象,需要实现IResourceCopy泛型接口。 /// </summary> public class StringBuilderCopy : IResourceCopy<StringBuilder> { #region IResourceCopy<StringBuilder> 成员 public void Copy(StringBuilder oriSb, StringBuilder rollsb) { oriSb.Remove(0, oriSb.Length); oriSb.Append(rollsb.ToString()); } #endregion } //代码4:将自定义的资源管理器参与到事务处理中 /// <summary> /// 事务范围内的登记资源管理对象的状态 /// </summary> public class EnlistmentDemo { [MethodImpl(MethodImplOptions.Synchronized)]//锁住当前方法,避免多线程访问破坏事务资源的一致性。 public void Start() { //易失性资源 StringBuilder stringvalues = new StringBuilder("123"); StringBuilder stringvalues2 = new StringBuilder("456"); StringBuilder stringvalues3 = new StringBuilder("789"); StringBuilder stringvalues4 = new StringBuilder("101112"); //使用资源管理器进行管理 IEnlistmentNotificationDemo<StringBuilder, StringBuilderCopy> resource = new IEnlistmentNotificationDemo<StringBuilder, StringBuilderCopy>(stringvalues, new StringBuilderCopy()); IEnlistmentNotificationDemo<StringBuilder, StringBuilderCopy> resource2 = new IEnlistmentNotificationDemo<StringBuilder, StringBuilderCopy>(stringvalues2, new StringBuilderCopy()); IEnlistmentNotificationDemo<StringBuilder, StringBuilderCopy> resource3 = new IEnlistmentNotificationDemo<StringBuilder, StringBuilderCopy>(stringvalues3, new StringBuilderCopy()); IEnlistmentNotificationDemo<StringBuilder, StringBuilderCopy> resource4 = new IEnlistmentNotificationDemo<StringBuilder, StringBuilderCopy>(stringvalues4, new StringBuilderCopy()); try { using (TransactionScope transcope = new TransactionScope()) { Transaction.Current.TransactionCompleted += new TransactionCompletedEventHandler(commitran_TransactionCompleted); //登记事务资源管理器,在开始一切事务性操作之前必须先登记资源管理器 Transaction.Current.EnlistVolatile(resource, EnlistmentOptions.None); Transaction.Current.EnlistVolatile(resource2, EnlistmentOptions.None); Transaction.Current.EnlistVolatile(resource3, EnlistmentOptions.None); Transaction.Current.EnlistVolatile(resource4, EnlistmentOptions.None); //开始事务性操作,该阶段属于事务的激活阶段。 stringvalues.Append("456"); stringvalues2.Append("789"); stringvalues3.Append("101112"); stringvalues4.Append("131415"); transcope.Complete();//开始两阶段提交,该阶段属于事务的准备阶段。 } } catch { Console.WriteLine("事务执行出错,执行回滚"); } //查看被事务性操作后的值 Console.WriteLine("事务完成后的结果值:"); Console.WriteLine(stringvalues + "|" + stringvalues2 + "|" + stringvalues3 + "|" + stringvalues4); } //事务结束时触发的事件方法,可以捕获事务执行结果。 void commitran_TransactionCompleted(object sender, TransactionEventArgs e) { Console.WriteLine("transaction completed:"); Console.WriteLine("ID: {0}", e.Transaction.TransactionInformation.LocalIdentifier); Console.WriteLine("Distributed ID: {0}", e.Transaction.TransactionInformation.DistributedIdentifier); Console.WriteLine("Status: {0}", e.Transaction.TransactionInformation.Status); Console.WriteLine("IsolationLevel: {0}", e.Transaction.IsolationLevel); } } class Program { static void Main(string[] args) { EnlistmentDemo svc = new EnlistmentDemo(); svc.Start(); Console.Read(); } } }