Beispiel #1
0
        // ITransactionPhase0NotifyAsync
        public void Phase0Request(
            bool abortingHint
            )
        {
            IEnlistmentNotificationInternal localEnlistmentNotification = null;
            OletxEnlistmentState localState = OletxEnlistmentState.Active;
            OletxCommittableTransaction committableTx = null;
            bool commitNotYetCalled = false;

            if ( DiagnosticTrace.Verbose )
            {
                MethodEnteredTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "OletxEnlistment.Phase0Request"
                    );
            }

            committableTx = this.oletxTransaction.realOletxTransaction.committableTransaction;
            if ( null != committableTx )
            {
                // We are dealing with the committable transaction.  If Commit or BeginCommit has NOT been
                // called, then we are dealing with a situation where the TM went down and we are getting
                // a bogus Phase0Request with abortHint = false (COMPlus bug 36760/36758).  This is an attempt
                // to not send the app a Prepare request when we know the transaction is going to abort.
                if (!committableTx.CommitCalled )
                {
                    commitNotYetCalled = true;
                }
            }

            lock ( this )
            {
                this.aborting = abortingHint;

                // 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 ( OletxEnlistmentState.Active == state )
                {
                    // If we got an abort hint or we are the committable transaction and Commit has not yet been called or the TM went down,
                    // we don't want to do any more work on the transaction.  The abort notifications will be sent by the phase 1
                    // enlistment
                    if ( ( this.aborting ) || ( commitNotYetCalled ) || ( this.tmWentDown ) )
                    {
                        // There is a possible ---- where we could get the Phase0Request before we are given the
                        // shim.  In that case, we will vote "no" when we are given the shim.
                        if ( null != this.phase0Shim )
                        {
                            try
                            {
                                this.phase0Shim.Phase0Done( false );
                            }
                            // I am not going to check for XACT_E_PROTOCOL here because that check is a workaround for a bug
                            // that only shows up if abortingHint is false.
                            catch ( COMException ex )
                            {
                                if ( DiagnosticTrace.Verbose )
                                {
                                    ExceptionConsumedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                                        ex );
                                }
                            }
                        }
                    }
                    else
                    {
                        localState = state = OletxEnlistmentState.Phase0Preparing;
                        localEnlistmentNotification = iEnlistmentNotification;
                    }
                }
            }

            // Tell the application to do the work.
            if ( null != localEnlistmentNotification )
            {
                if ( OletxEnlistmentState.Phase0Preparing == localState )
                {
                    byte[] txGuidArray = transactionGuid.ToByteArray();
                    byte[] rmGuidArray = oletxResourceManager.resourceManagerIdentifier.ToByteArray();
                    
                    byte[] temp = new byte[txGuidArray.Length + rmGuidArray.Length];
                    Thread.MemoryBarrier();
                    this.proxyPrepareInfoByteArray = temp;
                    int index = 0;
                    for ( index = 0; index < txGuidArray.Length; index++ )
                    {
                        proxyPrepareInfoByteArray[index] = 
                            txGuidArray[index];
                    }

                    for ( index = 0; index < rmGuidArray.Length; index++ )
                    {
                        proxyPrepareInfoByteArray[txGuidArray.Length + index] = 
                            rmGuidArray[index];
                    }

                    OletxRecoveryInformation oletxRecoveryInformation = new OletxRecoveryInformation(
                                                                            proxyPrepareInfoByteArray
                                                                            );
                    byte[] oletxRecoveryInformationByteArray = TransactionManager.ConvertToByteArray( oletxRecoveryInformation );

                    // 
                    this.prepareInfoByteArray = TransactionManager.GetRecoveryInformation(
                        oletxResourceManager.oletxTransactionManager.CreationNodeName,
                        oletxRecoveryInformationByteArray
                        );

                    if ( DiagnosticTrace.Verbose )
                    {
                        EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            this.InternalTraceIdentifier,
                            NotificationCall.Prepare
                            );
                    }

                    localEnlistmentNotification.Prepare( this );
                }
                else
                {
                    // We must have had a ---- between EnlistmentDone and the proxy telling
                    // us Phase0Request.  Just return.
                    if ( DiagnosticTrace.Verbose )
                    {
                        MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            "OletxEnlistment.Phase0Request"
                            );
                    }

                    return;
                }

            }
            if ( DiagnosticTrace.Verbose )
            {
                MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "OletxEnlistment.Phase0Request"
                    );
            }

        }
Beispiel #2
0
        // ITranactionResourceAsync.PrepareRequest
        public bool PrepareRequest(
            bool singlePhase,
            byte[] prepareInfo
            )
        {
            IEnlistmentShim localEnlistmentShim = null;
            OletxEnlistmentState localState = OletxEnlistmentState.Active;
            IEnlistmentNotificationInternal localEnlistmentNotification = null;
            OletxRecoveryInformation oletxRecoveryInformation = null;
            bool enlistmentDone;

            lock ( this )
            {
                if ( OletxEnlistmentState.Active == state )
                {
                    localState = state = OletxEnlistmentState.Preparing;
                }
                else
                {
                    // We must have done the prepare work in Phase0, so just remember what state we are
                    // in now.
                    localState = state;
                }

                localEnlistmentNotification = iEnlistmentNotification;

                localEnlistmentShim = this.EnlistmentShim;

                this.oletxTransaction.realOletxTransaction.TooLateForEnlistments = true;
            }

            // If we went to Preparing state, send the app
            // a prepare request.
            if ( OletxEnlistmentState.Preparing == localState )
            {
                oletxRecoveryInformation = new OletxRecoveryInformation( prepareInfo );
                this.isSinglePhase = singlePhase;

                // Store the prepare info we are given.
                Debug.Assert(this.proxyPrepareInfoByteArray == null, "Unexpected value in this.proxyPrepareInfoByteArray");
                long arrayLength = prepareInfo.Length;
                this.proxyPrepareInfoByteArray = new Byte[arrayLength];
                Array.Copy(prepareInfo, this.proxyPrepareInfoByteArray, arrayLength);

                if ( this.isSinglePhase && this.canDoSinglePhase )
                {
                    ISinglePhaseNotificationInternal singlePhaseNotification = (ISinglePhaseNotificationInternal) localEnlistmentNotification;
                    state = OletxEnlistmentState.SinglePhaseCommitting;
                    // We don't call DecrementUndecidedEnlistments for Phase1 enlistments.
                    if ( DiagnosticTrace.Verbose )
                    {
                        EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            this.InternalTraceIdentifier,
                            NotificationCall.SinglePhaseCommit
                            );
                    }

                    singlePhaseNotification.SinglePhaseCommit( this );
                    enlistmentDone = true;
                }
                else
                {
                    // We need to turn the oletxRecoveryInformation into a byte array.
                    byte[] oletxRecoveryInformationByteArray = TransactionManager.ConvertToByteArray( oletxRecoveryInformation );
                        
                    state = OletxEnlistmentState.Preparing;
                        
                    // 
                    this.prepareInfoByteArray = TransactionManager.GetRecoveryInformation(
                        oletxResourceManager.oletxTransactionManager.CreationNodeName,
                        oletxRecoveryInformationByteArray
                        );

                    if ( DiagnosticTrace.Verbose )
                    {
                        EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            this.InternalTraceIdentifier,
                            NotificationCall.Prepare
                            );
                    }

                    localEnlistmentNotification.Prepare(
                        this
                        );
                    enlistmentDone = false;
                }
            }
            else if ( OletxEnlistmentState.Prepared == localState )
            {
                // We must have done our prepare work during Phase0 so just vote Yes.
                try
                {
                    localEnlistmentShim.PrepareRequestDone( OletxPrepareVoteType.Prepared );
                    enlistmentDone = false;
                }
                catch ( COMException comException )
                {
                    OletxTransactionManager.ProxyException( comException );
                    throw;
                }
            }
            else if ( OletxEnlistmentState.Done == localState )
            {
                try
                {
                    // This was an early vote.  Respond ReadOnly
                    try
                    {
                        localEnlistmentShim.PrepareRequestDone( OletxPrepareVoteType.ReadOnly );
                        enlistmentDone = true;
                    }
                    finally
                    {
                        FinishEnlistment();
                    }
                }
                catch ( COMException comException )
                {
                    OletxTransactionManager.ProxyException( comException );
                    throw;
                }
            }
            else
            {
                // Any other state means we should vote NO to the proxy.
                try
                {
                    localEnlistmentShim.PrepareRequestDone( OletxPrepareVoteType.Failed );
                }
                catch ( COMException ex )
                {
                    // No point in rethrowing this.  We are not on an app thread and we have already told
                    // the app that the transaction is aborting.  When the app calls EnlistmentDone, we will
                    // do the final release of the ITransactionEnlistmentAsync.
                    if ( DiagnosticTrace.Verbose )
                    {
                        ExceptionConsumedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            ex );
                    }
                }
                enlistmentDone = true;
            }

            return enlistmentDone;
        }
        public bool PrepareRequest(bool singlePhase, byte[] prepareInfo)
        {
            IEnlistmentShim                 enlistmentShim          = null;
            OletxEnlistmentState            active                  = OletxEnlistmentState.Active;
            IEnlistmentNotificationInternal iEnlistmentNotification = null;
            OletxRecoveryInformation        thingToConvert          = null;

            lock (this)
            {
                if (this.state == OletxEnlistmentState.Active)
                {
                    active = this.state = OletxEnlistmentState.Preparing;
                }
                else
                {
                    active = this.state;
                }
                iEnlistmentNotification = this.iEnlistmentNotification;
                enlistmentShim          = this.EnlistmentShim;
                base.oletxTransaction.realOletxTransaction.TooLateForEnlistments = true;
            }
            if (OletxEnlistmentState.Preparing == active)
            {
                thingToConvert     = new OletxRecoveryInformation(prepareInfo);
                this.isSinglePhase = singlePhase;
                long length = prepareInfo.Length;
                this.proxyPrepareInfoByteArray = new byte[length];
                Array.Copy(prepareInfo, this.proxyPrepareInfoByteArray, length);
                if (this.isSinglePhase && this.canDoSinglePhase)
                {
                    ISinglePhaseNotificationInternal internal3 = (ISinglePhaseNotificationInternal)iEnlistmentNotification;
                    this.state = OletxEnlistmentState.SinglePhaseCommitting;
                    if (DiagnosticTrace.Verbose)
                    {
                        EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.SinglePhaseCommit);
                    }
                    internal3.SinglePhaseCommit(this);
                    return(true);
                }
                byte[] resourceManagerRecoveryInformation = TransactionManager.ConvertToByteArray(thingToConvert);
                this.state = OletxEnlistmentState.Preparing;
                this.prepareInfoByteArray = TransactionManager.GetRecoveryInformation(base.oletxResourceManager.oletxTransactionManager.CreationNodeName, resourceManagerRecoveryInformation);
                if (DiagnosticTrace.Verbose)
                {
                    EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Prepare);
                }
                iEnlistmentNotification.Prepare(this);
                return(false);
            }
            if (OletxEnlistmentState.Prepared == active)
            {
                try
                {
                    enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.Prepared);
                    return(false);
                }
                catch (COMException exception3)
                {
                    OletxTransactionManager.ProxyException(exception3);
                    throw;
                }
            }
            if (OletxEnlistmentState.Done == active)
            {
                try
                {
                    bool flag;
                    try
                    {
                        enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.ReadOnly);
                        flag = true;
                    }
                    finally
                    {
                        this.FinishEnlistment();
                    }
                    return(flag);
                }
                catch (COMException exception2)
                {
                    OletxTransactionManager.ProxyException(exception2);
                    throw;
                }
            }
            try
            {
                enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.Failed);
            }
            catch (COMException exception)
            {
                if (DiagnosticTrace.Verbose)
                {
                    ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
                }
            }
            return(true);
        }
        public void Phase0Request(bool abortingHint)
        {
            IEnlistmentNotificationInternal iEnlistmentNotification = null;
            OletxEnlistmentState            active = OletxEnlistmentState.Active;
            OletxCommittableTransaction     committableTransaction = null;
            bool flag = false;

            if (DiagnosticTrace.Verbose)
            {
                MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxEnlistment.Phase0Request");
            }
            committableTransaction = base.oletxTransaction.realOletxTransaction.committableTransaction;
            if ((committableTransaction != null) && !committableTransaction.CommitCalled)
            {
                flag = true;
            }
            lock (this)
            {
                this.aborting = abortingHint;
                if (this.state == OletxEnlistmentState.Active)
                {
                    if ((this.aborting || flag) || this.tmWentDown)
                    {
                        if (this.phase0Shim != null)
                        {
                            try
                            {
                                this.phase0Shim.Phase0Done(false);
                            }
                            catch (COMException exception)
                            {
                                if (DiagnosticTrace.Verbose)
                                {
                                    ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
                                }
                            }
                        }
                    }
                    else
                    {
                        active = this.state = OletxEnlistmentState.Phase0Preparing;
                        iEnlistmentNotification = this.iEnlistmentNotification;
                    }
                }
            }
            if (iEnlistmentNotification != null)
            {
                if (OletxEnlistmentState.Phase0Preparing != active)
                {
                    if (DiagnosticTrace.Verbose)
                    {
                        MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxEnlistment.Phase0Request");
                    }
                    return;
                }
                byte[] buffer  = this.transactionGuid.ToByteArray();
                byte[] buffer2 = base.oletxResourceManager.resourceManagerIdentifier.ToByteArray();
                byte[] buffer4 = new byte[buffer.Length + buffer2.Length];
                Thread.MemoryBarrier();
                this.proxyPrepareInfoByteArray = buffer4;
                int index = 0;
                for (index = 0; index < buffer.Length; index++)
                {
                    this.proxyPrepareInfoByteArray[index] = buffer[index];
                }
                for (index = 0; index < buffer2.Length; index++)
                {
                    this.proxyPrepareInfoByteArray[buffer.Length + index] = buffer2[index];
                }
                OletxRecoveryInformation thingToConvert   = new OletxRecoveryInformation(this.proxyPrepareInfoByteArray);
                byte[] resourceManagerRecoveryInformation = TransactionManager.ConvertToByteArray(thingToConvert);
                this.prepareInfoByteArray = TransactionManager.GetRecoveryInformation(base.oletxResourceManager.oletxTransactionManager.CreationNodeName, resourceManagerRecoveryInformation);
                if (DiagnosticTrace.Verbose)
                {
                    EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Prepare);
                }
                iEnlistmentNotification.Prepare(this);
            }
            if (DiagnosticTrace.Verbose)
            {
                MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxEnlistment.Phase0Request");
            }
        }
 public bool PrepareRequest(bool singlePhase, byte[] prepareInfo)
 {
     IEnlistmentShim enlistmentShim = null;
     OletxEnlistmentState active = OletxEnlistmentState.Active;
     IEnlistmentNotificationInternal iEnlistmentNotification = null;
     OletxRecoveryInformation thingToConvert = null;
     lock (this)
     {
         if (this.state == OletxEnlistmentState.Active)
         {
             active = this.state = OletxEnlistmentState.Preparing;
         }
         else
         {
             active = this.state;
         }
         iEnlistmentNotification = this.iEnlistmentNotification;
         enlistmentShim = this.EnlistmentShim;
         base.oletxTransaction.realOletxTransaction.TooLateForEnlistments = true;
     }
     if (OletxEnlistmentState.Preparing == active)
     {
         thingToConvert = new OletxRecoveryInformation(prepareInfo);
         this.isSinglePhase = singlePhase;
         long length = prepareInfo.Length;
         this.proxyPrepareInfoByteArray = new byte[length];
         Array.Copy(prepareInfo, this.proxyPrepareInfoByteArray, length);
         if (this.isSinglePhase && this.canDoSinglePhase)
         {
             ISinglePhaseNotificationInternal internal3 = (ISinglePhaseNotificationInternal) iEnlistmentNotification;
             this.state = OletxEnlistmentState.SinglePhaseCommitting;
             if (DiagnosticTrace.Verbose)
             {
                 EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.SinglePhaseCommit);
             }
             internal3.SinglePhaseCommit(this);
             return true;
         }
         byte[] resourceManagerRecoveryInformation = TransactionManager.ConvertToByteArray(thingToConvert);
         this.state = OletxEnlistmentState.Preparing;
         this.prepareInfoByteArray = TransactionManager.GetRecoveryInformation(base.oletxResourceManager.oletxTransactionManager.CreationNodeName, resourceManagerRecoveryInformation);
         if (DiagnosticTrace.Verbose)
         {
             EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Prepare);
         }
         iEnlistmentNotification.Prepare(this);
         return false;
     }
     if (OletxEnlistmentState.Prepared == active)
     {
         try
         {
             enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.Prepared);
             return false;
         }
         catch (COMException exception3)
         {
             OletxTransactionManager.ProxyException(exception3);
             throw;
         }
     }
     if (OletxEnlistmentState.Done == active)
     {
         try
         {
             bool flag;
             try
             {
                 enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.ReadOnly);
                 flag = true;
             }
             finally
             {
                 this.FinishEnlistment();
             }
             return flag;
         }
         catch (COMException exception2)
         {
             OletxTransactionManager.ProxyException(exception2);
             throw;
         }
     }
     try
     {
         enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.Failed);
     }
     catch (COMException exception)
     {
         if (DiagnosticTrace.Verbose)
         {
             ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
         }
     }
     return true;
 }
 public void Phase0Request(bool abortingHint)
 {
     IEnlistmentNotificationInternal iEnlistmentNotification = null;
     OletxEnlistmentState active = OletxEnlistmentState.Active;
     OletxCommittableTransaction committableTransaction = null;
     bool flag = false;
     if (DiagnosticTrace.Verbose)
     {
         MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxEnlistment.Phase0Request");
     }
     committableTransaction = base.oletxTransaction.realOletxTransaction.committableTransaction;
     if ((committableTransaction != null) && !committableTransaction.CommitCalled)
     {
         flag = true;
     }
     lock (this)
     {
         this.aborting = abortingHint;
         if (this.state == OletxEnlistmentState.Active)
         {
             if ((this.aborting || flag) || this.tmWentDown)
             {
                 if (this.phase0Shim != null)
                 {
                     try
                     {
                         this.phase0Shim.Phase0Done(false);
                     }
                     catch (COMException exception)
                     {
                         if (DiagnosticTrace.Verbose)
                         {
                             ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
                         }
                     }
                 }
             }
             else
             {
                 active = this.state = OletxEnlistmentState.Phase0Preparing;
                 iEnlistmentNotification = this.iEnlistmentNotification;
             }
         }
     }
     if (iEnlistmentNotification != null)
     {
         if (OletxEnlistmentState.Phase0Preparing != active)
         {
             if (DiagnosticTrace.Verbose)
             {
                 MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxEnlistment.Phase0Request");
             }
             return;
         }
         byte[] buffer = this.transactionGuid.ToByteArray();
         byte[] buffer2 = base.oletxResourceManager.resourceManagerIdentifier.ToByteArray();
         byte[] buffer4 = new byte[buffer.Length + buffer2.Length];
         Thread.MemoryBarrier();
         this.proxyPrepareInfoByteArray = buffer4;
         int index = 0;
         for (index = 0; index < buffer.Length; index++)
         {
             this.proxyPrepareInfoByteArray[index] = buffer[index];
         }
         for (index = 0; index < buffer2.Length; index++)
         {
             this.proxyPrepareInfoByteArray[buffer.Length + index] = buffer2[index];
         }
         OletxRecoveryInformation thingToConvert = new OletxRecoveryInformation(this.proxyPrepareInfoByteArray);
         byte[] resourceManagerRecoveryInformation = TransactionManager.ConvertToByteArray(thingToConvert);
         this.prepareInfoByteArray = TransactionManager.GetRecoveryInformation(base.oletxResourceManager.oletxTransactionManager.CreationNodeName, resourceManagerRecoveryInformation);
         if (DiagnosticTrace.Verbose)
         {
             EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Prepare);
         }
         iEnlistmentNotification.Prepare(this);
     }
     if (DiagnosticTrace.Verbose)
     {
         MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxEnlistment.Phase0Request");
     }
 }