static void Main(string[] args) { TMParser parser = new TMParser(); if (!parser.Parse(args)) { return; } var serverProv = new SoapServerFormatterSinkProvider { TypeFilterLevel = TypeFilterLevel.Full }; var clientProv = new SoapClientFormatterSinkProvider(); IDictionary props = new Hashtable(); props["port"] = Int32.Parse(parser["p"]); var 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 ); while (true) { Thread.Sleep(2000); TwoPhaseCommit.PrintMessage(); } }
public MyTM() { Console.WriteLine("TM: Transaction Manager instantiated"); // by default, the TwoPhaseCommit shall not have the debugging properties PrepareFail and CommitFail set TwoPhaseCommit.PrepareFail = false; TwoPhaseCommit.CommitFail = false; TwoPhaseCommit.StartUp(); _transactionScavengerThread = new Thread(TransactionScavenger) { Name = "TransactionScavengerThread" }; _transactionScavengerThread.Start(); }
/// <summary> /// Call from WC in response to a client's commit /// </summary> /// <param name="context"></param> public void Commit(TP.Transaction context) { WaitTillReady(); lock (_resourceManagersEnlistedInTransactions) { if (_resourceManagersEnlistedInTransactions.ContainsKey(context)) { CommitedTransaction trans = TwoPhaseCommit.Commit(context, _resourceManagersEnlistedInTransactions[context]); trans.DoneEvent.WaitOne(TransactionTimeout * 1000); _resourceManagersEnlistedInTransactions.Remove(context); } } Console.WriteLine(string.Format("TM: Transaction {0} commited", context.Id)); }
/// <summary> /// The method to do two phrase commit /// This method shall be hosted in a new thread. /// The caller can wait on the DoneEvent. /// </summary> public void StartCommit(bool prepareFail = false, bool commitFail = false) { this.prepareFail = prepareFail; this.commitFail = commitFail; bool isStepComplete = false; var list = this.ResouceManagers.ResourceManagers; for (int i = 0; i < list.Count; i++) { rmCommitStates[i] = CommitState.Committed; } TwoPhaseCommit.WriteLog(); Prepare(); if ((isStepComplete = this.stepWaitEvent.WaitOne(stepTimeout))) { TwoPhaseCommit.WriteLog(); isStepComplete = WaitStepWithExpBackoff(Commit); if (isStepComplete) { TwoPhaseCommit.WriteLog(); TwoPhaseCommit.DoneCommit(this.Context); DoneEvent.Set(); } else { string outstring = string.Format("2PC:Retry Commit {0}\r", this.Context.Id); this.Message += outstring; Console.Write(string.Format("2PC:Retry Commit {0}\r", this.Context.Id)); WaitStepWithExpBackoff(Commit); } } else { // Presume abort Rollback(); TwoPhaseCommit.WriteLog(); TwoPhaseCommit.DoneCommit(this.Context); DoneEvent.Set(); } }
/// <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)); }