コード例 #1
0
ファイル: OletxEnlistment.cs プロジェクト: JianwenSun/cc
        public void InDoubt(Exception e)
        {
            IEnlistmentShim localEnlistmentShim = null;
            if ( DiagnosticTrace.Verbose )
            {
                MethodEnteredTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "OletxSinglePhaseEnlistment.InDoubt"
                    );
            }

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

            lock ( this )
            {
                if (!isSinglePhase || (OletxEnlistmentState.SinglePhaseCommitting != state))
                {
                    throw TransactionException.CreateEnlistmentStateException( SR.GetString( SR.TraceSourceOletx ), null );
                }
                state = OletxEnlistmentState.InDoubt;
                localEnlistmentShim = this.EnlistmentShim;
            }

            lock ( this.oletxTransaction.realOletxTransaction )
            {
                if ( this.oletxTransaction.realOletxTransaction.innerException == null )
                {
                    this.oletxTransaction.realOletxTransaction.innerException = e;
                }
            }

            try
            {
                if ( null != localEnlistmentShim )
                {
                    localEnlistmentShim.PrepareRequestDone( OletxPrepareVoteType.InDoubt );
                }
            }
            catch ( COMException ex )
            {
                // If the TM went down during our call, there is nothing special we have to do because
                // the App doesn't expect any more notifications.
                if ( ( NativeMethods.XACT_E_CONNECTION_DOWN == ex.ErrorCode ) ||
                    ( NativeMethods.XACT_E_TMNOTAVAILABLE == ex.ErrorCode )
                    )
                {
                    if ( DiagnosticTrace.Verbose )
                    {
                        ExceptionConsumedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            ex );
                    }
                }
                else
                {
                    throw;
                }
            }
            finally
            {
                FinishEnlistment();
            }
            if ( DiagnosticTrace.Verbose )
            {
                MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "OletxSinglePhaseEnlistment.InDoubt"
                    );
            }
        }
コード例 #2
0
ファイル: OletxEnlistment.cs プロジェクト: JianwenSun/cc
        internal OletxEnlistment(
            IEnlistmentNotificationInternal enlistmentNotification,
            OletxTransactionStatus xactStatus,
            byte[] prepareInfoByteArray,
            OletxResourceManager oletxResourceManager
            ) : base( oletxResourceManager, null )
        {
            Guid myGuid = Guid.Empty;

            // This will get set later by the creator of this object after it
            // has enlisted with the proxy.
            this.enlistmentShim = null;
            this.phase0Shim = null;

            this.canDoSinglePhase = false;
            this.iEnlistmentNotification = enlistmentNotification;
            this.state = OletxEnlistmentState.Active;

            // Do this before we do any tracing because it will affect the trace identifiers that we generate.
            Debug.Assert( ( null != prepareInfoByteArray ),  
                "OletxEnlistment.ctor - null oletxTransaction without a prepareInfoByteArray" );

            int prepareInfoLength = prepareInfoByteArray.Length;
            this.proxyPrepareInfoByteArray = new byte[prepareInfoLength];
            Array.Copy(prepareInfoByteArray, proxyPrepareInfoByteArray, prepareInfoLength);

            byte[] txGuidByteArray = new byte[16];
            Array.Copy(proxyPrepareInfoByteArray, txGuidByteArray, 16);

            this.transactionGuid = new Guid( txGuidByteArray );
            this.transactionGuidString = this.transactionGuid.ToString();
            
            // If this is being created as part of a Reenlist and we already know the
            // outcome, then tell the application.
            switch (xactStatus)
            {
                case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_ABORTED:
                {
                    this.state = OletxEnlistmentState.Aborting;
                    if ( DiagnosticTrace.Verbose )
                    {
                        EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            this.InternalTraceIdentifier,
                            NotificationCall.Rollback
                            );
                    }

                    iEnlistmentNotification.Rollback( this );
                    break;
                }

                case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_COMMITTED:
                {
                    this.state = OletxEnlistmentState.Committing;
                    // We are going to send the notification to the RM.  We need to put the
                    // enlistment on the reenlistPendingList.  We lock the reenlistList because
                    // we have decided that is the lock that protects both lists.  The entry will
                    // be taken off the reenlistPendingList when the enlistment has
                    // EnlistmentDone called on it.  The enlistment will call
                    // RemoveFromReenlistPending.
                    lock ( oletxResourceManager.reenlistList )
                    {
                        oletxResourceManager.reenlistPendingList.Add( this );
                    }

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

                    iEnlistmentNotification.Commit( this );
                    break;
                }

                case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED:
                {
                    this.state = OletxEnlistmentState.Prepared;
                    lock ( oletxResourceManager.reenlistList )
                    {
                        oletxResourceManager.reenlistList.Add( this );
                        oletxResourceManager.StartReenlistThread();
                    }
                    break;
                }

                default:
                {
                    if ( DiagnosticTrace.Critical )
                    {
                        InternalErrorTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            SR.GetString( SR.OletxEnlistmentUnexpectedTransactionStatus )
                            );
                    }

                    throw TransactionException.Create( SR.GetString( SR.TraceSourceOletx ), SR.GetString( SR.OletxEnlistmentUnexpectedTransactionStatus ), null );
                }
            }

            if ( DiagnosticTrace.Information )
            {
                EnlistmentTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    this.InternalTraceIdentifier,
                    EnlistmentType.Durable,
                    EnlistmentOptions.None
                    );
            }

            // Always do this last in case anything prior to this fails.
            AddToEnlistmentTable();
        }
コード例 #3
0
ファイル: OletxEnlistment.cs プロジェクト: JianwenSun/cc
        public void Committed()
        {
            IEnlistmentShim localEnlistmentShim = null;
            if ( DiagnosticTrace.Verbose )
            {
                MethodEnteredTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "OletxSinglePhaseEnlistment.Committed"
                    );
                EnlistmentCallbackPositiveTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    this.InternalTraceIdentifier,
                    EnlistmentCallback.Committed
                    );
            }

            lock ( this )
            {
                if (!isSinglePhase || (OletxEnlistmentState.SinglePhaseCommitting != state))
                {
                    throw TransactionException.CreateEnlistmentStateException( SR.GetString( SR.TraceSourceOletx ), null );
                }
                state = OletxEnlistmentState.Committed;
                localEnlistmentShim = this.EnlistmentShim;
            }

            try
            {
                // This may be the result of a reenlist, which means we don't have a
                // reference to the proxy.
                if ( null != localEnlistmentShim )
                {
                    localEnlistmentShim.PrepareRequestDone( OletxPrepareVoteType.SinglePhase );
                }
            }
            catch ( COMException ex )
            {
                // If the TM went down during our call, there is nothing special we have to do because
                // the App doesn't expect any more notifications.
                if ( ( NativeMethods.XACT_E_CONNECTION_DOWN == ex.ErrorCode ) ||
                    ( NativeMethods.XACT_E_TMNOTAVAILABLE == ex.ErrorCode )
                    )
                {
                    if ( DiagnosticTrace.Verbose )
                    {
                        ExceptionConsumedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            ex );
                    }
                }
                else
                {
                    throw;
                }
            }
            finally
            {
                FinishEnlistment();
            }
            if ( DiagnosticTrace.Verbose )
            {
                MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "OletxSinglePhaseEnlistment.Committed"
                    );
            }
        }
        internal OletxEnlistment(IEnlistmentNotificationInternal enlistmentNotification, OletxTransactionStatus xactStatus, byte[] prepareInfoByteArray, OletxResourceManager oletxResourceManager) : base(oletxResourceManager, null)
        {
            this.transactionGuid = Guid.Empty;
            this.phase1Handle = IntPtr.Zero;
            this.enlistmentShim = null;
            this.phase0Shim = null;
            this.canDoSinglePhase = false;
            this.iEnlistmentNotification = enlistmentNotification;
            this.state = OletxEnlistmentState.Active;
            int length = prepareInfoByteArray.Length;
            this.proxyPrepareInfoByteArray = new byte[length];
            Array.Copy(prepareInfoByteArray, this.proxyPrepareInfoByteArray, length);
            byte[] destinationArray = new byte[0x10];
            Array.Copy(this.proxyPrepareInfoByteArray, destinationArray, 0x10);
            this.transactionGuid = new Guid(destinationArray);
            base.transactionGuidString = this.transactionGuid.ToString();
            switch (xactStatus)
            {
                case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED:
                    this.state = OletxEnlistmentState.Prepared;
                    lock (oletxResourceManager.reenlistList)
                    {
                        oletxResourceManager.reenlistList.Add(this);
                        oletxResourceManager.StartReenlistThread();
                        goto Label_01CD;
                    }
                    break;

                case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_ABORTED:
                    this.state = OletxEnlistmentState.Aborting;
                    if (DiagnosticTrace.Verbose)
                    {
                        EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Rollback);
                    }
                    this.iEnlistmentNotification.Rollback(this);
                    goto Label_01CD;

                case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_COMMITTED:
                    this.state = OletxEnlistmentState.Committing;
                    lock (oletxResourceManager.reenlistList)
                    {
                        oletxResourceManager.reenlistPendingList.Add(this);
                    }
                    if (DiagnosticTrace.Verbose)
                    {
                        EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Commit);
                    }
                    this.iEnlistmentNotification.Commit(this);
                    goto Label_01CD;
            }
            if (DiagnosticTrace.Critical)
            {
                InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("OletxEnlistmentUnexpectedTransactionStatus"));
            }
            throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("OletxEnlistmentUnexpectedTransactionStatus"), null);
        Label_01CD:
            if (DiagnosticTrace.Information)
            {
                EnlistmentTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentType.Durable, EnlistmentOptions.None);
            }
            base.AddToEnlistmentTable();
        }
コード例 #5
0
ファイル: OletxEnlistment.cs プロジェクト: JianwenSun/cc
        public void ForceRollback( Exception e )
        {
            IEnlistmentShim localEnlistmentShim = null;
            IPhase0EnlistmentShim localPhase0Shim = null;

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

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

            lock ( this )
            {
                if ( OletxEnlistmentState.Preparing == state )
                {
                    localEnlistmentShim = this.EnlistmentShim;
                }
                else if ( OletxEnlistmentState.Phase0Preparing == state )
                {
                    localPhase0Shim = this.Phase0EnlistmentShim;
                    if ( null != localPhase0Shim )
                    {

                        // We have a vote - decrement the undecided enlistment count.  We only do this
                        // if we are Phase0 enlistment.
                        oletxTransaction.realOletxTransaction.DecrementUndecidedEnlistments();
                    }

                }
                else
                {
                    throw TransactionException.CreateEnlistmentStateException( SR.GetString( SR.TraceSourceOletx ), null );
                }

                state = OletxEnlistmentState.Aborted;
            }

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

            try
            {
                if ( null != localEnlistmentShim )
                {
                    try
                    {
                        localEnlistmentShim.PrepareRequestDone( OletxPrepareVoteType.Failed );
                    }
                    finally
                    {
                        HandleTable.FreeHandle( this.phase1Handle );
                    }
                }

                if ( null != localPhase0Shim )
                {
                    localPhase0Shim.Phase0Done( false );
                }
//                else
                    // The TM must have gone down, thus causing our interface pointer to be
                    // invalidated.  The App doesn't expect any more notifications, so we can
                    // just finish the enlistment.
            }
            catch ( COMException ex )
            {
                // If the TM went down during our call, there is nothing special we have to do because
                // the App doesn't expect any more notifications.
                if ( ( NativeMethods.XACT_E_CONNECTION_DOWN == ex.ErrorCode ) ||
                    ( NativeMethods.XACT_E_TMNOTAVAILABLE == ex.ErrorCode )
                    )
                {
                    if ( DiagnosticTrace.Verbose )
                    {
                        ExceptionConsumedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            ex );
                    }
                }
                else
                {
                    throw;
                }
            }
            finally
            {
                FinishEnlistment();
            }
            if ( DiagnosticTrace.Verbose )
            {
                MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "OletxPreparingEnlistment.ForceRollback"
                    );
            }
        }
コード例 #6
0
ファイル: OletxEnlistment.cs プロジェクト: JianwenSun/cc
        // 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"
                    );
            }

        }
コード例 #7
0
ファイル: OletxEnlistment.cs プロジェクト: JianwenSun/cc
        internal OletxEnlistment(
            bool canDoSinglePhase,
            IEnlistmentNotificationInternal enlistmentNotification,
            Guid transactionGuid,
            EnlistmentOptions enlistmentOptions,
            OletxResourceManager oletxResourceManager,
            OletxTransaction oletxTransaction
            ) : base( oletxResourceManager, oletxTransaction )
        {
            Guid myGuid = Guid.Empty;

            // This will get set later by the creator of this object after it
            // has enlisted with the proxy.
            this.enlistmentShim = null;
            this.phase0Shim = null;

            this.canDoSinglePhase = canDoSinglePhase;
            this.iEnlistmentNotification = enlistmentNotification;
            this.state = OletxEnlistmentState.Active;
            this.transactionGuid = transactionGuid;

            this.proxyPrepareInfoByteArray = null;

            if ( DiagnosticTrace.Information )
            {
                EnlistmentTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    this.InternalTraceIdentifier,
                    EnlistmentType.Durable,
                    enlistmentOptions
                    );
            }

            // Always do this last incase anything earlier fails.
            AddToEnlistmentTable();
        }
 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;
 }
 internal OletxEnlistment(bool canDoSinglePhase, IEnlistmentNotificationInternal enlistmentNotification, Guid transactionGuid, EnlistmentOptions enlistmentOptions, OletxResourceManager oletxResourceManager, OletxTransaction oletxTransaction) : base(oletxResourceManager, oletxTransaction)
 {
     this.transactionGuid = Guid.Empty;
     this.phase1Handle = IntPtr.Zero;
     this.enlistmentShim = null;
     this.phase0Shim = null;
     this.canDoSinglePhase = canDoSinglePhase;
     this.iEnlistmentNotification = enlistmentNotification;
     this.state = OletxEnlistmentState.Active;
     this.transactionGuid = transactionGuid;
     this.proxyPrepareInfoByteArray = null;
     if (DiagnosticTrace.Information)
     {
         EnlistmentTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentType.Durable, enlistmentOptions);
     }
     base.AddToEnlistmentTable();
 }
コード例 #10
0
 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");
     }
 }
コード例 #11
0
 public void Prepared()
 {
     int num1 = System.Transactions.Oletx.NativeMethods.S_OK;
     IEnlistmentShim enlistmentShim = null;
     IPhase0EnlistmentShim shim = null;
     bool fabricateRollback = false;
     if (DiagnosticTrace.Verbose)
     {
         MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxPreparingEnlistment.Prepared");
         EnlistmentCallbackPositiveTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentCallback.Prepared);
     }
     lock (this)
     {
         if (OletxEnlistmentState.Preparing == this.state)
         {
             enlistmentShim = this.EnlistmentShim;
         }
         else
         {
             if (OletxEnlistmentState.Phase0Preparing != this.state)
             {
                 throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null);
             }
             shim = this.Phase0EnlistmentShim;
             if (base.oletxTransaction.realOletxTransaction.Doomed || this.fabricateRollback)
             {
                 this.fabricateRollback = true;
                 fabricateRollback = this.fabricateRollback;
             }
         }
         this.state = OletxEnlistmentState.Prepared;
     }
     try
     {
         if (enlistmentShim != null)
         {
             enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.Prepared);
         }
         else if (shim != null)
         {
             base.oletxTransaction.realOletxTransaction.DecrementUndecidedEnlistments();
             shim.Phase0Done(!fabricateRollback);
         }
         else
         {
             fabricateRollback = true;
         }
         if (fabricateRollback)
         {
             this.AbortRequest();
         }
     }
     catch (COMException exception)
     {
         if ((System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN == exception.ErrorCode) || (System.Transactions.Oletx.NativeMethods.XACT_E_TMNOTAVAILABLE == exception.ErrorCode))
         {
             if (DiagnosticTrace.Verbose)
             {
                 ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
             }
         }
         else
         {
             if (System.Transactions.Oletx.NativeMethods.XACT_E_PROTOCOL != exception.ErrorCode)
             {
                 throw;
             }
             this.Phase0EnlistmentShim = null;
             if (DiagnosticTrace.Verbose)
             {
                 ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
             }
         }
     }
     if (DiagnosticTrace.Verbose)
     {
         MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxPreparingEnlistment.Prepared");
     }
 }
コード例 #12
0
 public void InDoubt(Exception e)
 {
     IEnlistmentShim enlistmentShim = null;
     if (DiagnosticTrace.Verbose)
     {
         MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxSinglePhaseEnlistment.InDoubt");
     }
     if (DiagnosticTrace.Warning)
     {
         EnlistmentCallbackNegativeTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentCallback.InDoubt);
     }
     lock (this)
     {
         if (!this.isSinglePhase || (OletxEnlistmentState.SinglePhaseCommitting != this.state))
         {
             throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null);
         }
         this.state = OletxEnlistmentState.InDoubt;
         enlistmentShim = this.EnlistmentShim;
     }
     lock (base.oletxTransaction.realOletxTransaction)
     {
         if (base.oletxTransaction.realOletxTransaction.innerException == null)
         {
             base.oletxTransaction.realOletxTransaction.innerException = e;
         }
     }
     try
     {
         if (enlistmentShim != null)
         {
             enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.InDoubt);
         }
     }
     catch (COMException exception)
     {
         if ((System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN != exception.ErrorCode) && (System.Transactions.Oletx.NativeMethods.XACT_E_TMNOTAVAILABLE != exception.ErrorCode))
         {
             throw;
         }
         if (DiagnosticTrace.Verbose)
         {
             ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
         }
     }
     finally
     {
         this.FinishEnlistment();
     }
     if (DiagnosticTrace.Verbose)
     {
         MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxSinglePhaseEnlistment.InDoubt");
     }
 }
コード例 #13
0
 public void ForceRollback(Exception e)
 {
     IPhase0EnlistmentShim shim = null;
     IEnlistmentShim enlistmentShim = null;
     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);
     }
     lock (this)
     {
         if (OletxEnlistmentState.Preparing == this.state)
         {
             enlistmentShim = this.EnlistmentShim;
         }
         else
         {
             if (OletxEnlistmentState.Phase0Preparing != this.state)
             {
                 throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null);
             }
             shim = this.Phase0EnlistmentShim;
             if (shim != null)
             {
                 base.oletxTransaction.realOletxTransaction.DecrementUndecidedEnlistments();
             }
         }
         this.state = OletxEnlistmentState.Aborted;
     }
     Interlocked.CompareExchange<Exception>(ref base.oletxTransaction.realOletxTransaction.innerException, e, null);
     try
     {
         if (enlistmentShim != null)
         {
             try
             {
                 enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.Failed);
             }
             finally
             {
                 HandleTable.FreeHandle(this.phase1Handle);
             }
         }
         if (shim != null)
         {
             shim.Phase0Done(false);
         }
     }
     catch (COMException exception)
     {
         if ((System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN != exception.ErrorCode) && (System.Transactions.Oletx.NativeMethods.XACT_E_TMNOTAVAILABLE != exception.ErrorCode))
         {
             throw;
         }
         if (DiagnosticTrace.Verbose)
         {
             ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
         }
     }
     finally
     {
         this.FinishEnlistment();
     }
     if (DiagnosticTrace.Verbose)
     {
         MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxPreparingEnlistment.ForceRollback");
     }
 }
コード例 #14
0
 public void EnlistmentDone()
 {
     bool flag;
     if (DiagnosticTrace.Verbose)
     {
         MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxEnlistment.EnlistmentDone");
         EnlistmentCallbackPositiveTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentCallback.Done);
     }
     IEnlistmentShim enlistmentShim = null;
     IPhase0EnlistmentShim shim2 = null;
     OletxEnlistmentState active = OletxEnlistmentState.Active;
     bool fabricateRollback = false;
     lock (this)
     {
         active = this.state;
         if (this.state == OletxEnlistmentState.Active)
         {
             shim2 = this.Phase0EnlistmentShim;
             if (shim2 != null)
             {
                 base.oletxTransaction.realOletxTransaction.DecrementUndecidedEnlistments();
             }
             flag = false;
         }
         else if (OletxEnlistmentState.Preparing == this.state)
         {
             enlistmentShim = this.EnlistmentShim;
             flag = true;
         }
         else if (OletxEnlistmentState.Phase0Preparing == this.state)
         {
             shim2 = this.Phase0EnlistmentShim;
             base.oletxTransaction.realOletxTransaction.DecrementUndecidedEnlistments();
             if (this.fabricateRollback)
             {
                 flag = true;
             }
             else
             {
                 flag = false;
             }
         }
         else
         {
             if (((OletxEnlistmentState.Committing != this.state) && (OletxEnlistmentState.Aborting != this.state)) && (OletxEnlistmentState.SinglePhaseCommitting != this.state))
             {
                 throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null);
             }
             enlistmentShim = this.EnlistmentShim;
             flag = true;
         }
         fabricateRollback = this.fabricateRollback;
         this.state = OletxEnlistmentState.Done;
     }
     try
     {
         if (enlistmentShim != null)
         {
             if (OletxEnlistmentState.Preparing == active)
             {
                 try
                 {
                     enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.ReadOnly);
                     goto Label_01C1;
                 }
                 finally
                 {
                     HandleTable.FreeHandle(this.phase1Handle);
                 }
             }
             if (OletxEnlistmentState.Committing != active)
             {
                 if (OletxEnlistmentState.Aborting != active)
                 {
                     if (OletxEnlistmentState.SinglePhaseCommitting != active)
                     {
                         throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null);
                     }
                     enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.SinglePhase);
                 }
                 else if (!fabricateRollback)
                 {
                     enlistmentShim.AbortRequestDone();
                 }
             }
             else
             {
                 enlistmentShim.CommitRequestDone();
             }
         }
         else if (shim2 != null)
         {
             if (active != OletxEnlistmentState.Active)
             {
                 if (OletxEnlistmentState.Phase0Preparing != active)
                 {
                     throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null);
                 }
                 shim2.Phase0Done(true);
             }
             else
             {
                 shim2.Unenlist();
             }
         }
     }
     catch (COMException exception)
     {
         flag = true;
         if (DiagnosticTrace.Verbose)
         {
             ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
         }
     }
     finally
     {
         if (flag)
         {
             this.FinishEnlistment();
         }
     }
 Label_01C1:
     if (DiagnosticTrace.Verbose)
     {
         MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxEnlistment.EnlistmentDone");
     }
 }
コード例 #15
0
ファイル: OletxEnlistment.cs プロジェクト: JianwenSun/cc
        // 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;
        }
コード例 #16
0
        public void AbortRequest()
        {
            IEnlistmentShim enlistmentShim = null;
            IEnlistmentNotificationInternal iEnlistmentNotification = null;
            bool flag = false;

            lock (this)
            {
                if ((this.state == OletxEnlistmentState.Active) || (OletxEnlistmentState.Prepared == this.state))
                {
                    this.state = OletxEnlistmentState.Aborting;
                    iEnlistmentNotification = this.iEnlistmentNotification;
                }
                else
                {
                    if (OletxEnlistmentState.Phase0Preparing == this.state)
                    {
                        this.fabricateRollback = true;
                    }
                    else
                    {
                        flag = true;
                    }
                    enlistmentShim = this.EnlistmentShim;
                }
            }
            if (iEnlistmentNotification != null)
            {
                if (DiagnosticTrace.Verbose)
                {
                    EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Rollback);
                }
                iEnlistmentNotification.Rollback(this);
            }
            else if (enlistmentShim != null)
            {
                try
                {
                    enlistmentShim.AbortRequestDone();
                }
                catch (COMException exception)
                {
                    if ((System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN != exception.ErrorCode) && (System.Transactions.Oletx.NativeMethods.XACT_E_TMNOTAVAILABLE != exception.ErrorCode))
                    {
                        throw;
                    }
                    flag = true;
                    if (DiagnosticTrace.Verbose)
                    {
                        ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
                    }
                }
                finally
                {
                    if (flag)
                    {
                        this.FinishEnlistment();
                    }
                }
            }
        }
コード例 #17
0
ファイル: OletxEnlistment.cs プロジェクト: JianwenSun/cc
        public void AbortRequest()
        {
            OletxEnlistmentState localState = OletxEnlistmentState.Active;
            IEnlistmentNotificationInternal localEnlistmentNotification = null;
            IEnlistmentShim localEnlistmentShim = null;
            bool finishEnlistment = false;

            lock ( this )
            {
                if ( ( OletxEnlistmentState.Active == state ) ||
                     ( OletxEnlistmentState.Prepared == state )
                   )
                {
                    localState = state = OletxEnlistmentState.Aborting;
                    localEnlistmentNotification = iEnlistmentNotification;
                }
                else
                {
                    // We must have received an EnlistmentDone already or we have
                    // a notification outstanding (Phase0 prepare).
                    localState = state;
                    if ( OletxEnlistmentState.Phase0Preparing == state )
                    {
                        this.fabricateRollback = true;
                    }
                    else
                    {
                        finishEnlistment = true;
                    }

                    localEnlistmentShim = this.EnlistmentShim;
                }
            }

            if ( null != localEnlistmentNotification )
            {
                if ( DiagnosticTrace.Verbose )
                {
                    EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                        this.InternalTraceIdentifier,
                        NotificationCall.Rollback
                        );
                }

                localEnlistmentNotification.Rollback( this );
            }
            else if ( null != localEnlistmentShim )
            {
                // We need to respond to the proxy now.
                try
                {
                    localEnlistmentShim.AbortRequestDone();
                }
                catch ( COMException ex )
                {
                    // If the TM went down during our call, there is nothing special we have to do because
                    // the App doesn't expect any more notifications.  We do want to mark the enlistment
                    // to finish, however.
                    if ( ( NativeMethods.XACT_E_CONNECTION_DOWN == ex.ErrorCode ) ||
                        ( NativeMethods.XACT_E_TMNOTAVAILABLE == ex.ErrorCode )
                        )
                    {
                        finishEnlistment = true;
                        if ( DiagnosticTrace.Verbose )
                        {
                            ExceptionConsumedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                                ex );
                        }
                    }
                    else
                    {
                        throw;
                    }
                }
                finally
                {
                    if ( finishEnlistment )
                    {
                        FinishEnlistment();
                    }
                }
            }
            return;
        }
コード例 #18
0
        internal OletxEnlistment(IEnlistmentNotificationInternal enlistmentNotification, OletxTransactionStatus xactStatus, byte[] prepareInfoByteArray, OletxResourceManager oletxResourceManager) : base(oletxResourceManager, null)
        {
            this.transactionGuid         = Guid.Empty;
            this.phase1Handle            = IntPtr.Zero;
            this.enlistmentShim          = null;
            this.phase0Shim              = null;
            this.canDoSinglePhase        = false;
            this.iEnlistmentNotification = enlistmentNotification;
            this.state = OletxEnlistmentState.Active;
            int length = prepareInfoByteArray.Length;

            this.proxyPrepareInfoByteArray = new byte[length];
            Array.Copy(prepareInfoByteArray, this.proxyPrepareInfoByteArray, length);
            byte[] destinationArray = new byte[0x10];
            Array.Copy(this.proxyPrepareInfoByteArray, destinationArray, 0x10);
            this.transactionGuid       = new Guid(destinationArray);
            base.transactionGuidString = this.transactionGuid.ToString();
            switch (xactStatus)
            {
            case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED:
                this.state = OletxEnlistmentState.Prepared;
                lock (oletxResourceManager.reenlistList)
                {
                    oletxResourceManager.reenlistList.Add(this);
                    oletxResourceManager.StartReenlistThread();
                    goto Label_01CD;
                }
                break;

            case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_ABORTED:
                this.state = OletxEnlistmentState.Aborting;
                if (DiagnosticTrace.Verbose)
                {
                    EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Rollback);
                }
                this.iEnlistmentNotification.Rollback(this);
                goto Label_01CD;

            case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_COMMITTED:
                this.state = OletxEnlistmentState.Committing;
                lock (oletxResourceManager.reenlistList)
                {
                    oletxResourceManager.reenlistPendingList.Add(this);
                }
                if (DiagnosticTrace.Verbose)
                {
                    EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Commit);
                }
                this.iEnlistmentNotification.Commit(this);
                goto Label_01CD;
            }
            if (DiagnosticTrace.Critical)
            {
                InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("OletxEnlistmentUnexpectedTransactionStatus"));
            }
            throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("OletxEnlistmentUnexpectedTransactionStatus"), null);
Label_01CD:
            if (DiagnosticTrace.Information)
            {
                EnlistmentTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentType.Durable, EnlistmentOptions.None);
            }
            base.AddToEnlistmentTable();
        }
コード例 #19
0
ファイル: OletxEnlistment.cs プロジェクト: JianwenSun/cc
        public void EnlistmentDone()
        {
            if ( DiagnosticTrace.Verbose )
            {
                MethodEnteredTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "OletxEnlistment.EnlistmentDone"
                    );
                EnlistmentCallbackPositiveTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    this.InternalTraceIdentifier,
                    EnlistmentCallback.Done
                    );
            }

            IEnlistmentShim localEnlistmentShim = null;
            IPhase0EnlistmentShim localPhase0Shim = null;
            OletxEnlistmentState localState = OletxEnlistmentState.Active;
            bool finishEnlistment;
            bool localFabricateRollback = false;

            lock ( this )
            {
                localState = state;
                if ( OletxEnlistmentState.Active == state )
                {
                    // Early vote.  If we are doing Phase0, we need to unenlist.  Otherwise, just
                    // remember.
                    localPhase0Shim = this.Phase0EnlistmentShim;
                    if ( null != localPhase0Shim )
                    {
                        // We are a Phase0 enlistment and we have a vote - decrement the undecided enlistment count.
                        // We only do this for Phase0 because we don't count Phase1 durable enlistments.
                        oletxTransaction.realOletxTransaction.DecrementUndecidedEnlistments();
                    }
                    finishEnlistment = false;
                }
                else if ( OletxEnlistmentState.Preparing == state )
                {
                    // Read only vote.  Tell the proxy and go to the Done state.
                    localEnlistmentShim = this.EnlistmentShim;
                    // We don't decrement the undecided enlistment count for Preparing because we only count
                    // Phase0 enlistments and we are in Phase1 in Preparing state.
                    finishEnlistment = true;
                }
                else if ( OletxEnlistmentState.Phase0Preparing == state )
                {
                    // Read only vote to Phase0.  Tell the proxy okay and go to the Done state.
                    localPhase0Shim = this.Phase0EnlistmentShim;
                    // We are a Phase0 enlistment and we have a vote - decrement the undecided enlistment count.
                    // We only do this for Phase0 because we don't count Phase1 durable enlistments.
                    oletxTransaction.realOletxTransaction.DecrementUndecidedEnlistments();

                    // If we would have fabricated a rollback then we have already received an abort request
                    // from proxy and will not receive any more notifications.  Otherwise more notifications
                    // will be coming.
                    if ( this.fabricateRollback )
                    {
                        finishEnlistment = true;
                    }
                    else
                    {
                        finishEnlistment = false;
                    }
                }
                else if ( ( OletxEnlistmentState.Committing == state ) ||
                    ( OletxEnlistmentState.Aborting == state ) ||
                    ( OletxEnlistmentState.SinglePhaseCommitting == state )
                    )
                {
                    localEnlistmentShim = this.EnlistmentShim;
                    finishEnlistment = true;
                    // We don't decrement the undecided enlistment count for SinglePhaseCommitting because we only
                    // do it for Phase0 enlistments.
                }
                else
                {
                    throw TransactionException.CreateEnlistmentStateException( SR.GetString( SR.TraceSourceOletx ), null );
                }

                // If this.fabricateRollback is true, it means that we are fabricating this
                // AbortRequest, rather than having the proxy tell us.  So we don't need
                // to respond to the proxy with AbortRequestDone.
                localFabricateRollback = this.fabricateRollback;

                state = OletxEnlistmentState.Done;
            }

            try
            {
                if ( null != localEnlistmentShim )
                {
                    if ( OletxEnlistmentState.Preparing == localState )
                    {
                        try
                        {
                            localEnlistmentShim.PrepareRequestDone( OletxPrepareVoteType.ReadOnly );
                        }
                        finally
                        {
                            HandleTable.FreeHandle( this.phase1Handle );
                        }
                    }
                    else if ( OletxEnlistmentState.Committing == localState )
                    {
                        localEnlistmentShim.CommitRequestDone();
                    }
                    else if ( OletxEnlistmentState.Aborting == localState )
                    {
                        // If localFabricatRollback is true, it means that we are fabricating this
                        // AbortRequest, rather than having the proxy tell us.  So we don't need
                        // to respond to the proxy with AbortRequestDone.
                        if ( ! localFabricateRollback )
                        {
                            localEnlistmentShim.AbortRequestDone();
                        }
                    }
                    else if ( OletxEnlistmentState.SinglePhaseCommitting == localState )
                    {
                        localEnlistmentShim.PrepareRequestDone( OletxPrepareVoteType.SinglePhase );
                    }
                    else
                    {
                        throw TransactionException.CreateEnlistmentStateException( SR.GetString( SR.TraceSourceOletx ), null );
                    }
                }
                else if ( null != localPhase0Shim )
                {
                    if ( OletxEnlistmentState.Active == localState )
                    {
                        localPhase0Shim.Unenlist();
                    }
                    else if ( OletxEnlistmentState.Phase0Preparing == localState )
                    {
                        localPhase0Shim.Phase0Done( true );
                    }
                    else
                    {
                        throw TransactionException.CreateEnlistmentStateException( SR.GetString( SR.TraceSourceOletx ), null );
                    }
                }

            }
            catch ( COMException ex )
            {
                // If we get an error talking to the proxy, there is nothing special we have to do because
                // the App doesn't expect any more notifications.  We do want to mark the enlistment
                // to finish, however.
                finishEnlistment = true;

                if ( DiagnosticTrace.Verbose )
                {
                    ExceptionConsumedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                        ex );
                }
            }
            finally
            {
                if ( finishEnlistment )
                {
                    FinishEnlistment();
                }
            }
            if ( DiagnosticTrace.Verbose )
            {
                MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "OletxEnlistment.EnlistmentDone"
                    );
            }
        }
コード例 #20
0
        public void EnlistmentDone()
        {
            bool flag;

            if (DiagnosticTrace.Verbose)
            {
                MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxEnlistment.EnlistmentDone");
                EnlistmentCallbackPositiveTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentCallback.Done);
            }
            IEnlistmentShim       enlistmentShim = null;
            IPhase0EnlistmentShim shim2          = null;
            OletxEnlistmentState  active         = OletxEnlistmentState.Active;
            bool fabricateRollback = false;

            lock (this)
            {
                active = this.state;
                if (this.state == OletxEnlistmentState.Active)
                {
                    shim2 = this.Phase0EnlistmentShim;
                    if (shim2 != null)
                    {
                        base.oletxTransaction.realOletxTransaction.DecrementUndecidedEnlistments();
                    }
                    flag = false;
                }
                else if (OletxEnlistmentState.Preparing == this.state)
                {
                    enlistmentShim = this.EnlistmentShim;
                    flag           = true;
                }
                else if (OletxEnlistmentState.Phase0Preparing == this.state)
                {
                    shim2 = this.Phase0EnlistmentShim;
                    base.oletxTransaction.realOletxTransaction.DecrementUndecidedEnlistments();
                    if (this.fabricateRollback)
                    {
                        flag = true;
                    }
                    else
                    {
                        flag = false;
                    }
                }
                else
                {
                    if (((OletxEnlistmentState.Committing != this.state) && (OletxEnlistmentState.Aborting != this.state)) && (OletxEnlistmentState.SinglePhaseCommitting != this.state))
                    {
                        throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null);
                    }
                    enlistmentShim = this.EnlistmentShim;
                    flag           = true;
                }
                fabricateRollback = this.fabricateRollback;
                this.state        = OletxEnlistmentState.Done;
            }
            try
            {
                if (enlistmentShim != null)
                {
                    if (OletxEnlistmentState.Preparing == active)
                    {
                        try
                        {
                            enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.ReadOnly);
                            goto Label_01C1;
                        }
                        finally
                        {
                            HandleTable.FreeHandle(this.phase1Handle);
                        }
                    }
                    if (OletxEnlistmentState.Committing != active)
                    {
                        if (OletxEnlistmentState.Aborting != active)
                        {
                            if (OletxEnlistmentState.SinglePhaseCommitting != active)
                            {
                                throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null);
                            }
                            enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.SinglePhase);
                        }
                        else if (!fabricateRollback)
                        {
                            enlistmentShim.AbortRequestDone();
                        }
                    }
                    else
                    {
                        enlistmentShim.CommitRequestDone();
                    }
                }
                else if (shim2 != null)
                {
                    if (active != OletxEnlistmentState.Active)
                    {
                        if (OletxEnlistmentState.Phase0Preparing != active)
                        {
                            throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null);
                        }
                        shim2.Phase0Done(true);
                    }
                    else
                    {
                        shim2.Unenlist();
                    }
                }
            }
            catch (COMException exception)
            {
                flag = true;
                if (DiagnosticTrace.Verbose)
                {
                    ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
                }
            }
            finally
            {
                if (flag)
                {
                    this.FinishEnlistment();
                }
            }
Label_01C1:
            if (DiagnosticTrace.Verbose)
            {
                MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxEnlistment.EnlistmentDone");
            }
        }
コード例 #21
0
ファイル: OletxEnlistment.cs プロジェクト: JianwenSun/cc
        public void Prepared()
        {
            int hrResult = NativeMethods.S_OK;
            IEnlistmentShim localEnlistmentShim = null;
            IPhase0EnlistmentShim localPhase0Shim = null;
            bool localFabricateRollback = false;

            if ( DiagnosticTrace.Verbose )
            {
                MethodEnteredTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "OletxPreparingEnlistment.Prepared"
                    );
                EnlistmentCallbackPositiveTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    this.InternalTraceIdentifier,
                    EnlistmentCallback.Prepared
                    );
            }

            lock ( this )
            {
                if ( OletxEnlistmentState.Preparing == state )
                {
                    localEnlistmentShim = this.EnlistmentShim;
                }
                else if ( OletxEnlistmentState.Phase0Preparing == state )
                {
                    // If the transaction is doomed or we have fabricateRollback is true because the
                    // transaction aborted while the Phase0 Prepare request was outstanding,
                    // release the WrappedTransactionPhase0EnlistmentAsync and remember that
                    // we have a pending rollback.
                    localPhase0Shim = this.Phase0EnlistmentShim;
                    if ( ( oletxTransaction.realOletxTransaction.Doomed ) ||
                         ( this.fabricateRollback )
                       )
                    {
                        // Set fabricateRollback in case we got here because the transaction is doomed.
                        this.fabricateRollback = true;
                        localFabricateRollback = this.fabricateRollback;
                    }
                }
                else
                {
                    throw TransactionException.CreateEnlistmentStateException( SR.GetString( SR.TraceSourceOletx ), null );
                }

                state = OletxEnlistmentState.Prepared;

            }

            try
            {
                if ( null != localEnlistmentShim )
                {
                    localEnlistmentShim.PrepareRequestDone( OletxPrepareVoteType.Prepared );
                }
                else if ( null != localPhase0Shim )
                {
                    // We have a vote - decrement the undecided enlistment count.  We do
                    // this after checking Doomed because ForceRollback will decrement also.
                    // We also do this only for Phase0 enlistments.
                    oletxTransaction.realOletxTransaction.DecrementUndecidedEnlistments();

                    localPhase0Shim.Phase0Done( !localFabricateRollback );
                }

                else
                    // The TM must have gone down, thus causing our interface pointer to be
                    // invalidated.  So we need to drive abort of the enlistment as if we
                    // received an AbortRequest.
                {
                    localFabricateRollback = true;
                }
                
                if ( localFabricateRollback )
                {
                    AbortRequest();
                }
            }
            catch ( COMException ex )
            {
                // If the TM went down during our call, the TMDown notification to the enlistment
                // and RM will put this enlistment on the ReenlistList, if appropriate.  The outcome
                // will be obtained by the ReenlistThread.
                if ( ( NativeMethods.XACT_E_CONNECTION_DOWN == ex.ErrorCode ) ||
                    ( NativeMethods.XACT_E_TMNOTAVAILABLE == ex.ErrorCode )
                    )
                {
                    if ( DiagnosticTrace.Verbose )
                    {
                        ExceptionConsumedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            ex );
                    }
                }
                // In the case of Phase0, there is a bug in the proxy that causes an XACT_E_PROTOCOL
                // error if the TM goes down while the enlistment is still active.  The Phase0Request is
                // sent out with abortHint false, but the state of the proxy object is not changed, causing
                // Phase0Done request to fail with XACT_E_PROTOCOL.
                // For Prepared, we want to make sure the proxy aborts the transaction.  We don't need
                // to drive the abort to the application here because the Phase1 enlistment will do that.
                // In other words, treat this as if the proxy said Phase0Request( abortingHint = true ).
                else if ( NativeMethods.XACT_E_PROTOCOL == ex.ErrorCode )
                {
                    this.Phase0EnlistmentShim = null;
                    if ( DiagnosticTrace.Verbose )
                    {
                        ExceptionConsumedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            ex );
                    }
                }
                else
                {
                    throw;
                }
            }
            if ( DiagnosticTrace.Verbose )
            {
                MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "OletxPreparingEnlistment.Prepared"
                    );
            }
        }
コード例 #22
0
 public void CommitRequest()
 {
     IEnlistmentShim enlistmentShim = null;
     IEnlistmentNotificationInternal iEnlistmentNotification = null;
     bool flag = false;
     lock (this)
     {
         if (OletxEnlistmentState.Prepared == this.state)
         {
             this.state = OletxEnlistmentState.Committing;
             iEnlistmentNotification = this.iEnlistmentNotification;
         }
         else
         {
             enlistmentShim = this.EnlistmentShim;
             flag = true;
         }
     }
     if (iEnlistmentNotification != null)
     {
         if (DiagnosticTrace.Verbose)
         {
             EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Commit);
         }
         iEnlistmentNotification.Commit(this);
     }
     else if (enlistmentShim != null)
     {
         try
         {
             enlistmentShim.CommitRequestDone();
         }
         catch (COMException exception)
         {
             if ((System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN != exception.ErrorCode) && (System.Transactions.Oletx.NativeMethods.XACT_E_TMNOTAVAILABLE != exception.ErrorCode))
             {
                 throw;
             }
             flag = true;
             if (DiagnosticTrace.Verbose)
             {
                 ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
             }
         }
         finally
         {
             if (flag)
             {
                 this.FinishEnlistment();
             }
         }
     }
 }