static void Main(string[] args) { TMParser parser = new TMParser(); if (!parser.Parse(args)) { return; } SoapServerFormatterSinkProvider serverProv = new SoapServerFormatterSinkProvider(); serverProv.TypeFilterLevel = TypeFilterLevel.Full; SoapClientFormatterSinkProvider clientProv = new SoapClientFormatterSinkProvider(); IDictionary props = new Hashtable(); props["port"] = Int32.Parse(parser["p"]); HttpChannel channel = new HttpChannel(props, clientProv, serverProv); ChannelServices.RegisterChannel(channel, false); RemotingConfiguration.RegisterWellKnownServiceType (Type.GetType("MyTM.MyTM") // full type name , "TM.soap" // URI , System.Runtime.Remoting.WellKnownObjectMode.Singleton // instancing mode ); // activate the object string[] urls = channel.GetUrlsForUri("TM.soap"); if (1 != urls.Length) { throw new InvalidOperationException(); } MyTM transactionManager = (MyTM)System.Activator.GetObject(typeof(TP.TM), urls[0]); if (null == transactionManager) { throw new InvalidProgramException(); } // Do recovery every 30 seconds to recommit/reabort unacknowledged transactions // as well as doing garbage collection on the outstanding transaction file while (true) { Console.WriteLine("Recovery will run in 30 seconds..."); System.Threading.Thread.Sleep(30000); transactionManager.recovery(); } }
/// <summary> /// TM shall call this function when it restarts. /// if return is true /// 1. TM shall delete the transaction or retry commit if the state after recover is Rollbacked. /// 2. TM shall delete the transaction if the state after recover is done; /// if return is false /// TM shall retry the recover process; /// </summary> /// <return>false if the recover process failed.</return> public bool Recover() { foreach (RM rm in this.ResouceManagers.ResourceManagers) { RM inTM = null; while (inTM == null) { try { inTM = MyTM.StaticGetResourceMananger(rm.GetName()); } catch (WebException) { } if (inTM == null) { MyTM.StaticRegister(rm); } } } switch (State) { case CommitState.Committed: Rollback(); TwoPhaseCommit.WriteLog(); break; case CommitState.Prepared: Commit(); TwoPhaseCommit.WriteLog(); break; default: this.stepWaitEvent.Set(); break; } return(this.stepWaitEvent.WaitOne(stepTimeout)); }