事务处理 多步操作回滚
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; } } }
若有疑问或不正之处,欢迎提出指正和讨论