事务资源定义简单代码

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("\n由我投票整个事务回滚:" + _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();
        }
    }
}

 

posted on 2018-05-27 21:21  听哥哥的话  阅读(145)  评论(0编辑  收藏  举报

导航