事务处理 多步操作回滚

MSDN链接:http://msdn.microsoft.com/zh-cn/library/w97s6fw4(v=VS.80).aspx

class Program
{
    static void Main(string[] args)
    {
        try
        {
            using (TransactionScope transactionScope = new TransactionScope())
            {
                CustomEnlistment cstomEnlistment = new CustomEnlistment();
                cstomEnlistment.Preparing += new CustomEnlistment.PreparingEventHandler(() =>
                {
                    TestClass.Num1 = 1;
                    TestClass.Num2 = 2;
                    TestClass.Num3 = 3;
                    throw new Exception("Throw test error!");
                });
                cstomEnlistment.Rollbacking += new CustomEnlistment.RollbackingEventHandler(() =>
                {
                    TestClass.Num1 = 0;
                    TestClass.Num2 = 0;
                    TestClass.Num3 = 0;
                });

                Transaction.Current.EnlistVolatile(cstomEnlistment, EnlistmentOptions.None);
                Guid guid = new Guid("{3456789A-7654-2345-ABCD-098765434567}");
                Transaction.Current.EnlistDurable(guid, cstomEnlistment, EnlistmentOptions.None);
                transactionScope.Complete();
            }
        }
        catch
        {
            Console.WriteLine("Show error infomation!");
        }

        Thread.Sleep(1000);//事务单独开启线程异步执行,阻止主线程,用于测试效果
        Console.WriteLine(TestClass.Num1.ToString());
        Console.WriteLine(TestClass.Num2.ToString());
        Console.WriteLine(TestClass.Num3.ToString());
        Console.Read();
    }
}

//两阶段提交 (2PC)
public class CustomEnlistment : IEnlistmentNotification
{
    public delegate void PreparingEventHandler();
    public event PreparingEventHandler Preparing;

    public delegate void RollbackingEventHandler();
    public event RollbackingEventHandler Rollbacking;

    //准备,检查每组事务执行
    public void Prepare(PreparingEnlistment preparingEnlistment)
    {
        try
        {
            Preparing();
            preparingEnlistment.Prepared();//调用Commit
        }
        catch
        {
            preparingEnlistment.ForceRollback();//调用Rollback
        }
    }

    //提交
    public void Commit(Enlistment enlistment)
    {
        enlistment.Done();
    }

    //回滚
    public void Rollback(Enlistment enlistment)
    {
        Rollbacking();
        enlistment.Done();
    }

    //对于方法的说明来自于MSDN
    //应该为易失性资源管理器实现 InDoubt 方法。
    //在事务管理器失去与一个或多个参与者的联系(因此其状态未知)时调用此方法。
    //如果发生此情况,则无论是否有任何事务参与者处于不一致的状态,
    //您都应该记录此事实,以便以后进行调查。
    public void InDoubt(Enlistment enlistment)
    {
        enlistment.Done();
    }
}

/// <summary>
/// 测试类
/// </summary>
public class TestClass
{
    private static int num1 = 0;
    public static int Num1
    {
        get { return TestClass.num1; }
        set { TestClass.num1 = value; }
    }

    private static int num2 = 0;
    public static int Num2
    {
        get { return TestClass.num2; }
        set { TestClass.num2 = value; }
    }

    private static int num3 = 0;
    public static int Num3
    {
        get { return TestClass.num3; }
        set { TestClass.num3 = value; }
    }
}

若有疑问或不正之处,欢迎提出指正和讨论

posted @ 2011-10-13 11:33  iceknp  阅读(731)  评论(0编辑  收藏  举报