示例#1
0
        private TransactionException CreateVolatileEnlistment(System.Transactions.Transaction transactionToEnlist)
        {
            TransactionException         exception  = null;
            PersistenceContextEnlistment enlistment = null;
            int hashCode = transactionToEnlist.GetHashCode();

            lock (System.ServiceModel.Activities.Dispatcher.PersistenceContext.Enlistments)
            {
                try
                {
                    if (!System.ServiceModel.Activities.Dispatcher.PersistenceContext.Enlistments.TryGetValue(hashCode, out enlistment))
                    {
                        enlistment = new PersistenceContextEnlistment(this.PersistenceContext, transactionToEnlist);
                        transactionToEnlist.EnlistVolatile(enlistment, EnlistmentOptions.None);
                        System.ServiceModel.Activities.Dispatcher.PersistenceContext.Enlistments.Add(hashCode, enlistment);
                        return(exception);
                    }
                    enlistment.AddToEnlistment(this.PersistenceContext);
                    return(exception);
                }
                catch (TransactionException exception2)
                {
                    exception = exception2;
                    this.PersistenceContext.ScheduleNextTransactionWaiter();
                }
            }
            return(exception);
        }
示例#2
0
        internal static void DoPrepare(object state)
        {
            PersistenceContextEnlistment enlistment = state as PersistenceContextEnlistment;

            lock (enlistment.ThisLock)
            {
                enlistment.tooLateForMoreUndo = true;
            }
            enlistment.preparingEnlistment.Prepared();
        }
        internal static void DoPrepare(object state)
        {
            PersistenceContextEnlistment pcEnlist = state as PersistenceContextEnlistment;

            Fx.Assert(null != pcEnlist, "PersistenceContextEnlistment.DoPrepare called with an object that is not a PersistenceContext.");

            lock (pcEnlist.ThisLock)
            {
                pcEnlist.tooLateForMoreUndo = true;
            }

            // This needs to be done outside of the lock because it could induce System.Transactions
            // to do a whole bunch of other work inline, including issuing the Commit call and doing
            // Completion notifications for hte transaction. We don't want to be holding the lock
            // during all of that.
            pcEnlist.preparingEnlistment.Prepared();
        }
示例#4
0
        internal static void DoCommit(object state)
        {
            PersistenceContextEnlistment enlistment = state as PersistenceContextEnlistment;

            lock (enlistment.ThisLock)
            {
                foreach (PersistenceContext context in enlistment.enlistedContexts)
                {
                    context.ScheduleNextTransactionWaiter();
                }
            }
            lock (PersistenceContext.Enlistments)
            {
                PersistenceContext.Enlistments.Remove(enlistment.transaction.GetHashCode());
            }
            enlistment.enlistment.Done();
        }
示例#5
0
        internal static void DoRollback(object state)
        {
            PersistenceContextEnlistment enlistment = state as PersistenceContextEnlistment;

            lock (enlistment.ThisLock)
            {
                enlistment.tooLateForMoreUndo = true;
                foreach (PersistenceContext context in enlistment.enlistedContexts)
                {
                    context.Abort();
                    context.ScheduleNextTransactionWaiter();
                }
            }
            lock (PersistenceContext.Enlistments)
            {
                PersistenceContext.Enlistments.Remove(enlistment.transaction.GetHashCode());
            }
            enlistment.enlistment.Done();
        }
        internal static void DoCommit(object state)
        {
            PersistenceContextEnlistment pcEnlist = state as PersistenceContextEnlistment;

            Fx.Assert(null != pcEnlist, "PersistenceContextEnlistment.DoCommit called with an object that is not a PersistenceContext.");

            lock (pcEnlist.ThisLock)
            {
                // Wake up the next waiter for the pc, if any.
                foreach (PersistenceContext context in pcEnlist.enlistedContexts)
                {
                    context.ScheduleNextTransactionWaiter();
                }
            }
            lock (PersistenceContext.Enlistments)
            {
                PersistenceContext.Enlistments.Remove(pcEnlist.transaction.GetHashCode());
            }
            // This needs to be outside the lock because SysTx might do other stuff on the thread.
            pcEnlist.enlistment.Done();
        }
        internal static void DoIndoubt(object state)
        {
            PersistenceContextEnlistment pcEnlist = state as PersistenceContextEnlistment;

            Fx.Assert(null != pcEnlist, "PersistenceContextEnlistment.DoIndoubt called with an object that is not a PersistenceContext.");

            lock (pcEnlist.ThisLock)
            {
                pcEnlist.tooLateForMoreUndo = true;

                foreach (PersistenceContext context in pcEnlist.enlistedContexts)
                {
                    context.Abort();
                    context.ScheduleNextTransactionWaiter();
                }
            }
            lock (PersistenceContext.Enlistments)
            {
                PersistenceContext.Enlistments.Remove(pcEnlist.transaction.GetHashCode());
            }
            // This needs to be outside the lock because SysTx might do other stuff on the thread.
            pcEnlist.enlistment.Done();
        }
        TransactionException CreateVolatileEnlistment(Transaction transactionToEnlist)
        {
            TransactionException         result     = null;
            PersistenceContextEnlistment enlistment = null;
            int key = transactionToEnlist.GetHashCode();

            lock (PersistenceContext.Enlistments)
            {
                try
                {
                    if (!PersistenceContext.Enlistments.TryGetValue(key, out enlistment))
                    {
                        enlistment = new PersistenceContextEnlistment(this.PersistenceContext, transactionToEnlist);
                        transactionToEnlist.EnlistVolatile(enlistment, EnlistmentOptions.None);
                        // We don't save of the Enlistment object returned from EnlistVolatile. We don't need
                        // it here. When our PersistenceContextEnlistment object gets notified on Prepare,
                        // Commit, Rollback, or InDoubt, it is provided with the Enlistment object.
                        PersistenceContext.Enlistments.Add(key, enlistment);
                    }
                    else
                    {
                        enlistment.AddToEnlistment(this.PersistenceContext);
                    }
                }
                catch (TransactionException txException)
                {
                    result = txException;

                    // We own the lock but failed to create enlistment.  Manually wake up the next waiter.
                    // We only handle TransactionException, in case of other exception that failed to create enlistment,
                    // It will fallback to Timeout.  This is safe to avoid multiple waiters owning same lock.
                    this.PersistenceContext.ScheduleNextTransactionWaiter();
                }
            }
            return(result);
        }
        TransactionException CreateVolatileEnlistment(Transaction transactionToEnlist)
        {
            TransactionException result = null;
            PersistenceContextEnlistment enlistment = null;
            int key = transactionToEnlist.GetHashCode();
            lock (PersistenceContext.Enlistments)
            {
                try
                {
                    if (!PersistenceContext.Enlistments.TryGetValue(key, out enlistment))
                    {
                        enlistment = new PersistenceContextEnlistment(this.PersistenceContext, transactionToEnlist);
                        transactionToEnlist.EnlistVolatile(enlistment, EnlistmentOptions.None);
                        // We don't save of the Enlistment object returned from EnlistVolatile. We don't need
                        // it here. When our PersistenceContextEnlistment object gets notified on Prepare,
                        // Commit, Rollback, or InDoubt, it is provided with the Enlistment object.
                        PersistenceContext.Enlistments.Add(key, enlistment);
                    }
                    else
                    {
                        enlistment.AddToEnlistment(this.PersistenceContext);
                    }
                }
                catch (TransactionException txException)
                {
                    result = txException;

                    // We own the lock but failed to create enlistment.  Manually wake up the next waiter.
                    // We only handle TransactionException, in case of other exception that failed to create enlistment,
                    // It will fallback to Timeout.  This is safe to avoid multiple waiters owning same lock.
                    this.PersistenceContext.ScheduleNextTransactionWaiter();
                }
            }
            return result;
        }