/// <summary>
        /// Commits a transaction
        /// Initialize and recover from previous failure if necessary.
        /// See document for Init for details
        /// Use new thread to do two phrase commit on the transaction
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="rms"></param>
        /// <returns></returns>
        public static CommitedTransaction Commit(Transaction context, ResourceManagerList rms)
        {
            StartUp();

            CommitedTransaction trans = new CommitedTransaction(context, rms);
            lock (syncRoot)
            {
                if (!committedTransactions.ContainsKey(context))
                {
                    committedTransactions.Add(context, trans);
                }
                else
                {
                    trans = committedTransactions[context];
                }
            }

            ThreadPool.QueueUserWorkItem(o =>
                {
                    if (trans.State < CommitState.Committed)
                    {
                        trans.State = CommitState.Committed;
                        trans.StartCommit(PrepareFail, CommitFail);
                    }
                });
            return trans;
        }
        /// <summary>
        /// Commits a transaction
        /// Initialize and recover from previous failure if necessary.
        /// See document for Init for details
        /// Use new thread to do two phrase commit on the transaction
        ///
        /// </summary>
        /// <param name="context"></param>
        /// <param name="rms"></param>
        /// <returns></returns>
        public static CommitedTransaction Commit(Transaction context, ResourceManagerList rms)
        {
            StartUp();

            CommitedTransaction trans = new CommitedTransaction(context, rms);

            lock (syncRoot)
            {
                if (!committedTransactions.ContainsKey(context))
                {
                    committedTransactions.Add(context, trans);
                }
                else
                {
                    trans = committedTransactions[context];
                }
            }

            ThreadPool.QueueUserWorkItem(o =>
            {
                if (trans.State < CommitState.Committed)
                {
                    trans.State = CommitState.Committed;
                    trans.StartCommit(PrepareFail, CommitFail);
                }
            });
            return(trans);
        }
示例#3
0
 /// <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>
        /// Initialize the class
        /// If the log file exists, it will try to recover from previous run first by looking for
        /// committed transactions which are in CommitState.Committed || CommitState.Prepared state.
        /// </summary>
        public static void StartUp()
        {
            lock (syncRoot)
            {
                if (!isInitialized)
                {
                    if (File.Exists(LogFileName))
                    {
                        string line;
                        lock (committedTransactions)
                        {
                            committedTransactions = new Dictionary <Transaction, CommitedTransaction>();
                            using (StreamReader reader = new StreamReader(LogFileName))
                            {
                                while ((line = reader.ReadLine()) != null)
                                {
                                    if (!string.IsNullOrWhiteSpace(line))
                                    {
                                        CommitedTransaction trans = CommitedTransaction.FromString(line);
                                        // only recover the transaction which needs to be recovered
                                        if (trans.State == CommitState.Committed || trans.State == CommitState.Prepared)
                                        {
                                            committedTransactions[trans.Context] = trans;
                                        }
                                    }
                                }
                            }
                        }
                    }

                    isInitialized = true;

                    // The DB recovery code shall have locked the resources before this statement.
                    // Therefore, the subsequential query on the modified resources will be blocked until the recover process is finished
                    foreach (CommitedTransaction trans in committedTransactions.Values)
                    {
                        if (trans.State == CommitState.Committed || trans.State == CommitState.Prepared)
                        {
                            trans.Recover();
                        }
                    }
                }
            }
        }
示例#5
0
        public static CommitedTransaction FromString(string input)
        {
            string[]    items = input.Split(new char[] { '\t' }, StringSplitOptions.None);
            Transaction trans = new Transaction();

            trans.Id = new Guid(items[0]);
            string[]            rms = items[2].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            ResourceManagerList rml = new ResourceManagerList();

            foreach (string s in rms)
            {
                RM rm = new MyRM.MyRM();
                rm.SetName(s);
                rml.Add(rm);
            }

            CommitedTransaction result = new CommitedTransaction(trans, rml);

            switch (items[1])
            {
            case "None":
                result.State = CommitState.None;
                break;

            case "Committed":
                result.State = CommitState.Committed;
                break;

            case "Prepared":
                result.State = CommitState.Prepared;
                break;

            case "Done":
                result.State = CommitState.Done;
                break;
            }

            for (int i = 0; i < result.rmCommitStates.Count; i++)
            {
                result.rmCommitStates[i] = result.State;
            }
            return(result);
        }
        public static CommitedTransaction FromString(string input)
        {
            string[] items = input.Split(new char[] { '\t' }, StringSplitOptions.None);
            Transaction trans = new Transaction();
            trans.Id = new Guid(items[0]);
            string[] rms = items[2].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            ResourceManagerList rml = new ResourceManagerList();
            foreach (string s in rms)
            {
                RM rm = new MyRM.MyRM();
                rm.SetName(s);
                rml.Add(rm);
            }

            CommitedTransaction result = new CommitedTransaction(trans, rml);
            switch (items[1])
            {
                case "None":
                    result.State = CommitState.None;
                    break;
                case "Committed":
                    result.State = CommitState.Committed;
                    break;
                case "Prepared":
                    result.State = CommitState.Prepared;
                    break;
                case "Done":
                    result.State = CommitState.Done;
                    break;
            }

            for (int i = 0; i < result.rmCommitStates.Count; i++)
            {
                result.rmCommitStates[i] = result.State;
            }
            return result;
        }