예제 #1
0
        void IPromotedEnlistment.EnlistmentDone()
        {
            if (DiagnosticTrace.Verbose)
            {
                MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxEnlistment.EnlistmentDone");
                EnlistmentCallbackPositiveTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentCallback.Done);
            }
            OletxVolatileEnlistmentState     active    = OletxVolatileEnlistmentState.Active;
            OletxVolatileEnlistmentContainer container = null;

            lock (this)
            {
                active    = this.state;
                container = this.container;
                if ((((this.state != OletxVolatileEnlistmentState.Active) && (OletxVolatileEnlistmentState.Preparing != this.state)) && ((OletxVolatileEnlistmentState.Aborting != this.state) && (OletxVolatileEnlistmentState.Committing != this.state))) && (OletxVolatileEnlistmentState.InDoubt != this.state))
                {
                    throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null);
                }
                this.state = OletxVolatileEnlistmentState.Done;
            }
            if ((OletxVolatileEnlistmentState.Preparing == active) && (container != null))
            {
                container.DecrementOutstandingNotifications(true);
            }
            if (DiagnosticTrace.Verbose)
            {
                MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxEnlistment.EnlistmentDone");
            }
        }
예제 #2
0
        internal void Prepare(OletxVolatileEnlistmentContainer container)
        {
            OletxVolatileEnlistmentState    active = OletxVolatileEnlistmentState.Active;
            IEnlistmentNotificationInternal iEnlistmentNotification = null;

            lock (this)
            {
                iEnlistmentNotification = this.iEnlistmentNotification;
                if (this.state == OletxVolatileEnlistmentState.Active)
                {
                    active = this.state = OletxVolatileEnlistmentState.Preparing;
                }
                else
                {
                    active = this.state;
                }
                this.container = container;
            }
            if (OletxVolatileEnlistmentState.Preparing == active)
            {
                if (iEnlistmentNotification != null)
                {
                    if (DiagnosticTrace.Verbose)
                    {
                        EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Prepare);
                    }
                    iEnlistmentNotification.Prepare(this);
                    return;
                }
                if (DiagnosticTrace.Critical)
                {
                    InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
                }
                throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
            }
            if (OletxVolatileEnlistmentState.Done == active)
            {
                container.DecrementOutstandingNotifications(true);
            }
            else if ((OletxVolatileEnlistmentState.Prepared == active) && this.enlistDuringPrepareRequired)
            {
                container.DecrementOutstandingNotifications(true);
            }
            else if ((OletxVolatileEnlistmentState.Aborting == active) || (OletxVolatileEnlistmentState.Aborted == active))
            {
                container.DecrementOutstandingNotifications(false);
            }
            else
            {
                if (DiagnosticTrace.Critical)
                {
                    InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
                }
                throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
            }
        }
예제 #3
0
        void IPromotedEnlistment.Prepared()
        {
            if (DiagnosticTrace.Verbose)
            {
                MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxPreparingEnlistment.Prepared");
                EnlistmentCallbackPositiveTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentCallback.Prepared);
            }
            OletxVolatileEnlistmentContainer container = null;
            TransactionStatus active = TransactionStatus.Active;

            lock (this)
            {
                if (OletxVolatileEnlistmentState.Preparing != this.state)
                {
                    throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null);
                }
                this.state = OletxVolatileEnlistmentState.Prepared;
                active     = this.pendingOutcome;
                if (this.container == null)
                {
                    if (DiagnosticTrace.Critical)
                    {
                        InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
                    }
                    throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
                }
                container = this.container;
            }
            container.DecrementOutstandingNotifications(true);
            switch (active)
            {
            case TransactionStatus.Active:
                break;

            case TransactionStatus.Aborted:
                this.Rollback();
                break;

            case TransactionStatus.InDoubt:
                this.InDoubt();
                break;

            default:
                if (DiagnosticTrace.Critical)
                {
                    InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
                }
                throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
            }
            if (DiagnosticTrace.Verbose)
            {
                MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxPreparingEnlistment.Prepared");
            }
        }
예제 #4
0
        internal void InDoubt()
        {
            OletxVolatileEnlistmentState    active = OletxVolatileEnlistmentState.Active;
            IEnlistmentNotificationInternal iEnlistmentNotification = null;

            lock (this)
            {
                if (OletxVolatileEnlistmentState.Prepared == this.state)
                {
                    active = this.state = OletxVolatileEnlistmentState.InDoubt;
                    iEnlistmentNotification = this.iEnlistmentNotification;
                }
                else
                {
                    if (OletxVolatileEnlistmentState.Preparing == this.state)
                    {
                        this.pendingOutcome = TransactionStatus.InDoubt;
                    }
                    active = this.state;
                }
            }
            if (OletxVolatileEnlistmentState.InDoubt == active)
            {
                if (iEnlistmentNotification != null)
                {
                    if (DiagnosticTrace.Verbose)
                    {
                        EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.InDoubt);
                    }
                    iEnlistmentNotification.InDoubt(this);
                    return;
                }
                if (DiagnosticTrace.Critical)
                {
                    InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
                }
                throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
            }
            if ((OletxVolatileEnlistmentState.Preparing != active) && (OletxVolatileEnlistmentState.Done != active))
            {
                if (DiagnosticTrace.Critical)
                {
                    InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
                }
                throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
            }
        }
 internal void InDoubt()
 {
     OletxVolatileEnlistmentState active = OletxVolatileEnlistmentState.Active;
     IEnlistmentNotificationInternal iEnlistmentNotification = null;
     lock (this)
     {
         if (OletxVolatileEnlistmentState.Prepared == this.state)
         {
             active = this.state = OletxVolatileEnlistmentState.InDoubt;
             iEnlistmentNotification = this.iEnlistmentNotification;
         }
         else
         {
             if (OletxVolatileEnlistmentState.Preparing == this.state)
             {
                 this.pendingOutcome = TransactionStatus.InDoubt;
             }
             active = this.state;
         }
     }
     if (OletxVolatileEnlistmentState.InDoubt == active)
     {
         if (iEnlistmentNotification != null)
         {
             if (DiagnosticTrace.Verbose)
             {
                 EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.InDoubt);
             }
             iEnlistmentNotification.InDoubt(this);
             return;
         }
         if (DiagnosticTrace.Critical)
         {
             InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
         }
         throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
     }
     if ((OletxVolatileEnlistmentState.Preparing != active) && (OletxVolatileEnlistmentState.Done != active))
     {
         if (DiagnosticTrace.Critical)
         {
             InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
         }
         throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
     }
 }
예제 #6
0
        void IPromotedEnlistment.ForceRollback(Exception e)
        {
            if (DiagnosticTrace.Verbose)
            {
                MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxPreparingEnlistment.ForceRollback");
            }
            if (DiagnosticTrace.Warning)
            {
                EnlistmentCallbackNegativeTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentCallback.ForceRollback);
            }
            OletxVolatileEnlistmentContainer container = null;

            lock (this)
            {
                if (OletxVolatileEnlistmentState.Preparing != this.state)
                {
                    throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null);
                }
                this.state = OletxVolatileEnlistmentState.Done;
                if (this.container == null)
                {
                    if (DiagnosticTrace.Critical)
                    {
                        InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
                    }
                    throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
                }
                container = this.container;
            }
            Interlocked.CompareExchange <Exception>(ref base.oletxTransaction.realOletxTransaction.innerException, e, null);
            container.DecrementOutstandingNotifications(false);
            if (DiagnosticTrace.Verbose)
            {
                MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxPreparingEnlistment.ForceRollback");
            }
        }
        void IPromotedEnlistment.Prepared()
        {
            if (DiagnosticTrace.Verbose)
            {
                MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxPreparingEnlistment.Prepared");
                EnlistmentCallbackPositiveTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentCallback.Prepared);
            }
            OletxVolatileEnlistmentContainer container = null;
            TransactionStatus active = TransactionStatus.Active;
            lock (this)
            {
                if (OletxVolatileEnlistmentState.Preparing != this.state)
                {
                    throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null);
                }
                this.state = OletxVolatileEnlistmentState.Prepared;
                active = this.pendingOutcome;
                if (this.container == null)
                {
                    if (DiagnosticTrace.Critical)
                    {
                        InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
                    }
                    throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
                }
                container = this.container;
            }
            container.DecrementOutstandingNotifications(true);
            switch (active)
            {
                case TransactionStatus.Active:
                    break;

                case TransactionStatus.Aborted:
                    this.Rollback();
                    break;

                case TransactionStatus.InDoubt:
                    this.InDoubt();
                    break;

                default:
                    if (DiagnosticTrace.Critical)
                    {
                        InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
                    }
                    throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
            }
            if (DiagnosticTrace.Verbose)
            {
                MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxPreparingEnlistment.Prepared");
            }
        }
 void IPromotedEnlistment.ForceRollback(Exception e)
 {
     if (DiagnosticTrace.Verbose)
     {
         MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxPreparingEnlistment.ForceRollback");
     }
     if (DiagnosticTrace.Warning)
     {
         EnlistmentCallbackNegativeTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentCallback.ForceRollback);
     }
     OletxVolatileEnlistmentContainer container = null;
     lock (this)
     {
         if (OletxVolatileEnlistmentState.Preparing != this.state)
         {
             throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null);
         }
         this.state = OletxVolatileEnlistmentState.Done;
         if (this.container == null)
         {
             if (DiagnosticTrace.Critical)
             {
                 InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
             }
             throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
         }
         container = this.container;
     }
     Interlocked.CompareExchange<Exception>(ref base.oletxTransaction.realOletxTransaction.innerException, e, null);
     container.DecrementOutstandingNotifications(false);
     if (DiagnosticTrace.Verbose)
     {
         MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxPreparingEnlistment.ForceRollback");
     }
 }
 void IPromotedEnlistment.EnlistmentDone()
 {
     if (DiagnosticTrace.Verbose)
     {
         MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxEnlistment.EnlistmentDone");
         EnlistmentCallbackPositiveTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentCallback.Done);
     }
     OletxVolatileEnlistmentState active = OletxVolatileEnlistmentState.Active;
     OletxVolatileEnlistmentContainer container = null;
     lock (this)
     {
         active = this.state;
         container = this.container;
         if ((((this.state != OletxVolatileEnlistmentState.Active) && (OletxVolatileEnlistmentState.Preparing != this.state)) && ((OletxVolatileEnlistmentState.Aborting != this.state) && (OletxVolatileEnlistmentState.Committing != this.state))) && (OletxVolatileEnlistmentState.InDoubt != this.state))
         {
             throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null);
         }
         this.state = OletxVolatileEnlistmentState.Done;
     }
     if ((OletxVolatileEnlistmentState.Preparing == active) && (container != null))
     {
         container.DecrementOutstandingNotifications(true);
     }
     if (DiagnosticTrace.Verbose)
     {
         MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxEnlistment.EnlistmentDone");
     }
 }
 internal void Prepare(OletxVolatileEnlistmentContainer container)
 {
     OletxVolatileEnlistmentState active = OletxVolatileEnlistmentState.Active;
     IEnlistmentNotificationInternal iEnlistmentNotification = null;
     lock (this)
     {
         iEnlistmentNotification = this.iEnlistmentNotification;
         if (this.state == OletxVolatileEnlistmentState.Active)
         {
             active = this.state = OletxVolatileEnlistmentState.Preparing;
         }
         else
         {
             active = this.state;
         }
         this.container = container;
     }
     if (OletxVolatileEnlistmentState.Preparing == active)
     {
         if (iEnlistmentNotification != null)
         {
             if (DiagnosticTrace.Verbose)
             {
                 EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Prepare);
             }
             iEnlistmentNotification.Prepare(this);
             return;
         }
         if (DiagnosticTrace.Critical)
         {
             InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
         }
         throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
     }
     if (OletxVolatileEnlistmentState.Done == active)
     {
         container.DecrementOutstandingNotifications(true);
     }
     else if ((OletxVolatileEnlistmentState.Prepared == active) && this.enlistDuringPrepareRequired)
     {
         container.DecrementOutstandingNotifications(true);
     }
     else if ((OletxVolatileEnlistmentState.Aborting == active) || (OletxVolatileEnlistmentState.Aborted == active))
     {
         container.DecrementOutstandingNotifications(false);
     }
     else
     {
         if (DiagnosticTrace.Critical)
         {
             InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
         }
         throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
     }
 }
예제 #11
0
        void IPromotedEnlistment.ForceRollback(Exception e)
        {
            if ( DiagnosticTrace.Verbose )
            {
                MethodEnteredTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "OletxPreparingEnlistment.ForceRollback"
                    );
            }

            if ( DiagnosticTrace.Warning )
            {
                EnlistmentCallbackNegativeTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    this.InternalTraceIdentifier,
                    EnlistmentCallback.ForceRollback
                    );
            }

            OletxVolatileEnlistmentContainer localContainer = null;

            lock ( this )
            {
                if ( OletxVolatileEnlistmentState.Preparing != state )
                {
                    throw TransactionException.CreateEnlistmentStateException( SR.GetString( SR.TraceSourceOletx ), null, this.DistributedTxId );
                }

                // There are no more notifications that need to happen on this enlistment.
                state = OletxVolatileEnlistmentState.Done;

                if ( null == container )
                {
                    if ( DiagnosticTrace.Critical )
                    {
                        InternalErrorTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            ""
                            );
                    }

                    Debug.Assert( false, "OletxVolatileEnlistment.ForceRollback, no container member." );
                    throw new InvalidOperationException( SR.GetString( SR.InternalError ) );
                }
                
                localContainer = container;
            }

            Interlocked.CompareExchange<Exception>( ref this.oletxTransaction.realOletxTransaction.innerException, e, null );

            // Vote no.
            localContainer.DecrementOutstandingNotifications( false );

            if ( DiagnosticTrace.Verbose )
            {
                MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "OletxPreparingEnlistment.ForceRollback"
                    );
            }
        }
예제 #12
0
        void IPromotedEnlistment.Prepared()
        {
            if ( DiagnosticTrace.Verbose )
            {
                MethodEnteredTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "OletxPreparingEnlistment.Prepared"
                    );
                EnlistmentCallbackPositiveTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    this.InternalTraceIdentifier,
                    EnlistmentCallback.Prepared
                    );
            }

            OletxVolatileEnlistmentContainer localContainer = null;
            TransactionStatus localPendingOutcome = TransactionStatus.Active;

            lock ( this )
            {
                if ( OletxVolatileEnlistmentState.Preparing != state )
                {
                    throw TransactionException.CreateEnlistmentStateException( SR.GetString( SR.TraceSourceOletx ), null, this.DistributedTxId );
                }

                state = OletxVolatileEnlistmentState.Prepared;
                localPendingOutcome = pendingOutcome;

                if ( null == container )
                {
                    if ( DiagnosticTrace.Critical )
                    {
                        InternalErrorTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            ""
                            );
                    }

                    Debug.Assert( false, "OletxVolatileEnlistment.Prepared, no container member." );
                    throw new InvalidOperationException( SR.GetString( SR.InternalError ) );
                }
                
                localContainer = container;
            }

            // Vote yes.
            localContainer.DecrementOutstandingNotifications( true );

            switch ( localPendingOutcome )
            {
                case TransactionStatus.Active:
                {
                    // nothing to do.  Everything is proceeding as normal.
                    break;
                }
                case TransactionStatus.Aborted:
                {
                    // The transaction aborted while the Prepare was outstanding.
                    // We need to tell the app to rollback.
                    Rollback();
                    break;
                }
                case TransactionStatus.InDoubt:
                {
                    // The transaction went InDoubt while the Prepare was outstanding.
                    // We need to tell the app.
                    InDoubt();
                    break;
                }
                default:
                {
                    // This shouldn't happen.
                    if ( DiagnosticTrace.Critical )
                    {
                        InternalErrorTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            ""
                            );
                    }

                    Debug.Assert( false, "OletxVolatileEnlistment.Prepared, invalid pending outcome value." );
                    throw new InvalidOperationException( SR.GetString( SR.InternalError ) );
                }
            }


            if ( DiagnosticTrace.Verbose )
            {
                MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "OletxPreparingEnlistment.Prepared"
                    );
            }
        }
예제 #13
0
        void IPromotedEnlistment.EnlistmentDone()
        {
            if ( DiagnosticTrace.Verbose )
            {
                MethodEnteredTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "OletxEnlistment.EnlistmentDone"
                    );
                EnlistmentCallbackPositiveTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    this.InternalTraceIdentifier,
                    EnlistmentCallback.Done
                    );
            }

            OletxVolatileEnlistmentState localState = OletxVolatileEnlistmentState.Active;
            OletxVolatileEnlistmentContainer localContainer = null;

            lock ( this )
            {
                localState = state;
                localContainer = container;

                if ( ( OletxVolatileEnlistmentState.Active != state ) &&
                     ( OletxVolatileEnlistmentState.Preparing != state ) &&
                     ( OletxVolatileEnlistmentState.Aborting != state ) &&
                     ( OletxVolatileEnlistmentState.Committing != state ) &&
                     ( OletxVolatileEnlistmentState.InDoubt != state )
                   )
                {
                    throw TransactionException.CreateEnlistmentStateException( SR.GetString( SR.TraceSourceOletx ), null, this.DistributedTxId );
                }

                state = OletxVolatileEnlistmentState.Done;
            }

            // For the Preparing state, we need to decrement the outstanding
            // count with the container.  If the state is Active, it is an early vote so we
            // just stay in the Done state and when we get the Prepare, we will vote appropriately.
            if ( OletxVolatileEnlistmentState.Preparing == localState )
            {
                if ( null != localContainer )
                {
                    // Specify true.  If aborting, it is okay because the transaction is already
                    // aborting.
                    localContainer.DecrementOutstandingNotifications( true );
                }
            }

            if ( DiagnosticTrace.Verbose )
            {
                MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "OletxEnlistment.EnlistmentDone"
                    );
            }
        }
예제 #14
0
        internal void InDoubt()
        {
            OletxVolatileEnlistmentState localState = OletxVolatileEnlistmentState.Active;
            IEnlistmentNotificationInternal localEnlistmentNotification = null;

            lock ( this )
            {
                // The app may have already called EnlistmentDone.  If this occurs, don't bother sending
                // the notification to the app and we don't need to tell the proxy.
                if ( OletxVolatileEnlistmentState.Prepared == state )
                {
                    localState = state = OletxVolatileEnlistmentState.InDoubt;
                    localEnlistmentNotification = iEnlistmentNotification;
                }
                else
                {
                    if ( OletxVolatileEnlistmentState.Preparing == state )
                    {
                        pendingOutcome = TransactionStatus.InDoubt;
                    }
                    localState = state;
                }
            }

            // Tell the application to do the work.
            if ( OletxVolatileEnlistmentState.InDoubt == localState )
            {
                if ( null != localEnlistmentNotification )
                {
                    if ( DiagnosticTrace.Verbose )
                    {
                        EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            this.InternalTraceIdentifier,
                            NotificationCall.InDoubt
                            );
                    }

                    localEnlistmentNotification.InDoubt( this );
                }
                else
                {
                    if ( DiagnosticTrace.Critical )
                    {
                        InternalErrorTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            ""
                            );
                    }

                    Debug.Assert( false, "OletxVolatileEnlistment.InDoubt, no enlistmentNotification member." );
                    throw new InvalidOperationException( SR.GetString( SR.InternalError ) );
                }
            }
            else if ( OletxVolatileEnlistmentState.Preparing == localState )
            {
                // We have already set pendingOutcome, so there is nothing else to do.
            }
            else if ( OletxVolatileEnlistmentState.Done == localState )
            {
                // Early Exit - state was Done
            }
            else
            {
                if ( DiagnosticTrace.Critical )
                {
                    InternalErrorTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                        ""
                        );
                }

                Debug.Assert( false, "OletxVolatileEnlistment.InDoubt, invalid state." );
                throw new InvalidOperationException( SR.GetString( SR.InternalError ) );
            }

        }
예제 #15
0
        internal void Rollback()
        {
            OletxVolatileEnlistmentState localState = OletxVolatileEnlistmentState.Active;
            IEnlistmentNotificationInternal localEnlistmentNotification = null;

            lock ( this )
            {
                // The app may have already called EnlistmentDone.  If this occurs, don't bother sending
                // the notification to the app and we don't need to tell the proxy.
                if ( ( OletxVolatileEnlistmentState.Prepared == state ) ||
                    ( OletxVolatileEnlistmentState.Active == state )
                    )
                {
                    localState = state = OletxVolatileEnlistmentState.Aborting;
                    localEnlistmentNotification = iEnlistmentNotification;
                }
                else
                {
                    if ( OletxVolatileEnlistmentState.Preparing == state )
                    {
                        pendingOutcome = TransactionStatus.Aborted;
                    }
                    localState = state;
                }
            }

            // Tell the application to do the work.
            if ( OletxVolatileEnlistmentState.Aborting == localState )
            {
                if ( null != localEnlistmentNotification )
                {
                    if ( DiagnosticTrace.Verbose )
                    {
                        EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            this.InternalTraceIdentifier,
                            NotificationCall.Rollback
                            );
                    }

                    localEnlistmentNotification.Rollback( this );
                }

                // There is a small ---- where Rollback could be called when the enlistment is already
                // aborting the transaciton, so just ignore that call.  When the app enlistment
                // finishes responding to its Rollback notification with EnlistmentDone, things will get
                // cleaned up.
            }
            else if ( OletxVolatileEnlistmentState.Preparing == localState )
            {
                // We need to tolerate this state, but we have already marked the
                // enlistment as pendingRollback, so there is nothing else to do here.
            }
            else if ( OletxVolatileEnlistmentState.Done == localState )
            {
                // Early Exit - state was Done
            }
            else
            {
                if ( DiagnosticTrace.Critical )
                {
                    InternalErrorTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                        ""
                        );
                }

                Debug.Assert( false, "OletxVolatileEnlistment.Rollback, invalid state." );
                throw new InvalidOperationException( SR.GetString( SR.InternalError ) );
            }

        }
예제 #16
0
        internal void Prepare( OletxVolatileEnlistmentContainer container )
        {
            OletxVolatileEnlistmentState localState = OletxVolatileEnlistmentState.Active;
            IEnlistmentNotificationInternal localEnlistmentNotification = null;

            lock ( this )
            {
                localEnlistmentNotification = iEnlistmentNotification;

                // The app may have already called EnlistmentDone.  If this occurs, don't bother sending
                // the notification to the app.
                if ( OletxVolatileEnlistmentState.Active == state )
                {
                    localState = state = OletxVolatileEnlistmentState.Preparing;
                }
                else
                {
                    localState = state;
                }
                this.container = container;

            }

            // Tell the application to do the work.
            if ( OletxVolatileEnlistmentState.Preparing == localState )
            {
                if ( null != localEnlistmentNotification )
                {
                    if ( DiagnosticTrace.Verbose )
                    {
                        EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            this.InternalTraceIdentifier,
                            NotificationCall.Prepare
                            );
                    }

                    localEnlistmentNotification.Prepare( this );
                }
                else
                {
                    if ( DiagnosticTrace.Critical )
                    {
                        InternalErrorTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            ""
                            );
                    }

                    Debug.Assert( false, "OletxVolatileEnlistment.Prepare, no enlistmentNotification member." );
                    throw new InvalidOperationException( SR.GetString( SR.InternalError ) );
                }
            }
            else if ( OletxVolatileEnlistmentState.Done == localState )
            {
                // Voting yes because it was an early read-only vote.
                container.DecrementOutstandingNotifications( true );

                // We must have had a ---- between EnlistmentDone and the proxy telling
                // us Phase0Request.  Just return.
                return;
            }
            // It is okay to be in Prepared state if we are edpr=true because we already
            // did our prepare in Phase0.
            else if ( ( OletxVolatileEnlistmentState.Prepared == localState ) &&
                        ( this.enlistDuringPrepareRequired ) )
            {
                container.DecrementOutstandingNotifications( true );
                return;
            }
            else if ( ( OletxVolatileEnlistmentState.Aborting == localState ) ||
                      ( OletxVolatileEnlistmentState.Aborted == localState ) )
            {
                // An abort has ----d with this volatile Prepare
                // decrement the outstanding notifications making sure to vote no.
                container.DecrementOutstandingNotifications( false );
                return;
            }
            else
            {
                if ( DiagnosticTrace.Critical )
                {
                    InternalErrorTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                        ""
                        );
                }

                Debug.Assert( false, "OletxVolatileEnlistment.Prepare, invalid state." );
                throw new InvalidOperationException( SR.GetString( SR.InternalError ) );
            }

        }