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();
                    }
                }
            }
        }
Esempio n. 2
0
        internal void Commit()
        {
            OletxVolatileEnlistmentState    active = OletxVolatileEnlistmentState.Active;
            IEnlistmentNotificationInternal iEnlistmentNotification = null;

            lock (this)
            {
                if (OletxVolatileEnlistmentState.Prepared == this.state)
                {
                    active = this.state = OletxVolatileEnlistmentState.Committing;
                    iEnlistmentNotification = this.iEnlistmentNotification;
                }
                else
                {
                    active = this.state;
                }
            }
            if (OletxVolatileEnlistmentState.Committing == active)
            {
                if (iEnlistmentNotification != null)
                {
                    if (DiagnosticTrace.Verbose)
                    {
                        EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Commit);
                    }
                    iEnlistmentNotification.Commit(this);
                    return;
                }
                if (DiagnosticTrace.Critical)
                {
                    InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
                }
                throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
            }
            if (OletxVolatileEnlistmentState.Done != active)
            {
                if (DiagnosticTrace.Critical)
                {
                    InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
                }
                throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
            }
        }
Esempio n. 3
0
        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();
        }