コード例 #1
0
ファイル: OletxEnlistment.cs プロジェクト: mikem8361/runtime
    internal OletxEnlistment(
        bool canDoSinglePhase,
        IEnlistmentNotificationInternal enlistmentNotification,
        Guid transactionGuid,
        EnlistmentOptions enlistmentOptions,
        OletxResourceManager oletxResourceManager,
        OletxTransaction oletxTransaction)
        : base(oletxResourceManager, oletxTransaction)
    {
        // This will get set later by the creator of this object after it
        // has enlisted with the proxy.
        EnlistmentShim = null;
        _phase0Shim    = null;

        _canDoSinglePhase        = canDoSinglePhase;
        _iEnlistmentNotification = enlistmentNotification;
        State            = OletxEnlistmentState.Active;
        _transactionGuid = transactionGuid;

        _proxyPrepareInfoByteArray = null;

        TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

        if (etwLog.IsEnabled())
        {
            etwLog.EnlistmentCreated(TraceSourceType.TraceSourceOleTx, InternalTraceIdentifier, EnlistmentType.Durable, enlistmentOptions);
        }

        // Always do this last in case anything earlier fails.
        AddToEnlistmentTable();
    }
コード例 #2
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();
        }
コード例 #3
0
        internal void Prepare(OletxVolatileEnlistmentContainer container)
        {
            OletxVolatileEnlistmentState    active = OletxVolatileEnlistmentState.Active;
            IEnlistmentNotificationInternal iEnlistmentNotification = null;

            lock (this)
            {
                iEnlistmentNotification = this.iEnlistmentNotification;
                if (this.state == OletxVolatileEnlistmentState.Active)
                {
                    active = this.state = OletxVolatileEnlistmentState.Preparing;
                }
                else
                {
                    active = this.state;
                }
                this.container = container;
            }
            if (OletxVolatileEnlistmentState.Preparing == active)
            {
                if (iEnlistmentNotification != null)
                {
                    if (DiagnosticTrace.Verbose)
                    {
                        EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Prepare);
                    }
                    iEnlistmentNotification.Prepare(this);
                    return;
                }
                if (DiagnosticTrace.Critical)
                {
                    InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
                }
                throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
            }
            if (OletxVolatileEnlistmentState.Done == active)
            {
                container.DecrementOutstandingNotifications(true);
            }
            else if ((OletxVolatileEnlistmentState.Prepared == active) && this.enlistDuringPrepareRequired)
            {
                container.DecrementOutstandingNotifications(true);
            }
            else if ((OletxVolatileEnlistmentState.Aborting == active) || (OletxVolatileEnlistmentState.Aborted == active))
            {
                container.DecrementOutstandingNotifications(false);
            }
            else
            {
                if (DiagnosticTrace.Critical)
                {
                    InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
                }
                throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
            }
        }
コード例 #4
0
 internal OletxVolatileEnlistment(IEnlistmentNotificationInternal enlistmentNotification, EnlistmentOptions enlistmentOptions, OletxTransaction oletxTransaction) : base(null, oletxTransaction)
 {
     this.iEnlistmentNotification     = enlistmentNotification;
     this.enlistDuringPrepareRequired = (enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None;
     this.container      = null;
     this.pendingOutcome = TransactionStatus.Active;
     if (DiagnosticTrace.Information)
     {
         EnlistmentTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentType.Volatile, enlistmentOptions);
     }
 }
コード例 #5
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();
                    }
                }
            }
        }
 internal OletxVolatileEnlistment(IEnlistmentNotificationInternal enlistmentNotification, EnlistmentOptions enlistmentOptions, OletxTransaction oletxTransaction) : base(null, oletxTransaction)
 {
     this.iEnlistmentNotification = enlistmentNotification;
     this.enlistDuringPrepareRequired = (enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None;
     this.container = null;
     this.pendingOutcome = TransactionStatus.Active;
     if (DiagnosticTrace.Information)
     {
         EnlistmentTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentType.Volatile, enlistmentOptions);
     }
 }
コード例 #7
0
 internal void FinishEnlistment()
 {
     lock (this)
     {
         if (this.enlistmentShim == null)
         {
             base.oletxResourceManager.RemoveFromReenlistPending(this);
         }
         this.iEnlistmentNotification = null;
         base.RemoveFromEnlistmentTable();
     }
 }
コード例 #8
0
        internal void InDoubt()
        {
            OletxVolatileEnlistmentState    active = OletxVolatileEnlistmentState.Active;
            IEnlistmentNotificationInternal iEnlistmentNotification = null;

            lock (this)
            {
                if (OletxVolatileEnlistmentState.Prepared == this.state)
                {
                    active = this.state = OletxVolatileEnlistmentState.InDoubt;
                    iEnlistmentNotification = this.iEnlistmentNotification;
                }
                else
                {
                    if (OletxVolatileEnlistmentState.Preparing == this.state)
                    {
                        this.pendingOutcome = TransactionStatus.InDoubt;
                    }
                    active = this.state;
                }
            }
            if (OletxVolatileEnlistmentState.InDoubt == active)
            {
                if (iEnlistmentNotification != null)
                {
                    if (DiagnosticTrace.Verbose)
                    {
                        EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.InDoubt);
                    }
                    iEnlistmentNotification.InDoubt(this);
                    return;
                }
                if (DiagnosticTrace.Critical)
                {
                    InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
                }
                throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
            }
            if ((OletxVolatileEnlistmentState.Preparing != active) && (OletxVolatileEnlistmentState.Done != active))
            {
                if (DiagnosticTrace.Critical)
                {
                    InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
                }
                throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
            }
        }
 internal void InDoubt()
 {
     OletxVolatileEnlistmentState active = OletxVolatileEnlistmentState.Active;
     IEnlistmentNotificationInternal iEnlistmentNotification = null;
     lock (this)
     {
         if (OletxVolatileEnlistmentState.Prepared == this.state)
         {
             active = this.state = OletxVolatileEnlistmentState.InDoubt;
             iEnlistmentNotification = this.iEnlistmentNotification;
         }
         else
         {
             if (OletxVolatileEnlistmentState.Preparing == this.state)
             {
                 this.pendingOutcome = TransactionStatus.InDoubt;
             }
             active = this.state;
         }
     }
     if (OletxVolatileEnlistmentState.InDoubt == active)
     {
         if (iEnlistmentNotification != null)
         {
             if (DiagnosticTrace.Verbose)
             {
                 EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.InDoubt);
             }
             iEnlistmentNotification.InDoubt(this);
             return;
         }
         if (DiagnosticTrace.Critical)
         {
             InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
         }
         throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
     }
     if ((OletxVolatileEnlistmentState.Preparing != active) && (OletxVolatileEnlistmentState.Done != active))
     {
         if (DiagnosticTrace.Critical)
         {
             InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
         }
         throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
     }
 }
コード例 #10
0
 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();
 }
コード例 #11
0
        internal IPromotedEnlistment EnlistVolatile(IEnlistmentNotificationInternal enlistmentNotification, EnlistmentOptions enlistmentOptions)
        {
            if (DiagnosticTrace.Verbose)
            {
                MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxTransaction.EnlistVolatile( IEnlistmentNotificationInternal )");
            }
            if ((this.realOletxTransaction == null) || this.realOletxTransaction.TooLateForEnlistments)
            {
                throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TooLate"), null);
            }
            IPromotedEnlistment enlistment = this.realOletxTransaction.EnlistVolatile(enlistmentNotification, enlistmentOptions, this);

            if (DiagnosticTrace.Verbose)
            {
                MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxTransaction.EnlistVolatile( IEnlistmentNotificationInternal )");
            }
            return(enlistment);
        }
コード例 #12
0
        internal OletxEnlistment ReenlistTransaction(
            Guid resourceManagerIdentifier,
            byte[] recoveryInformation,
            IEnlistmentNotificationInternal enlistmentNotification
            )
        {
            if (null == recoveryInformation)
            {
                throw new ArgumentNullException("recoveryInformation");
            }

            if (null == enlistmentNotification)
            {
                throw new ArgumentNullException("enlistmentNotification");
            }

            // Now go find the resource manager in the collection.
            OletxResourceManager oletxResourceManager = RegisterResourceManager(resourceManagerIdentifier);

            if (null == oletxResourceManager)
            {
                throw new ArgumentException(SR.GetString(SR.InvalidArgument), "resourceManagerIdentifier");
            }

            if (oletxResourceManager.RecoveryCompleteCalledByApplication)
            {
                throw new InvalidOperationException(SR.GetString(SR.ReenlistAfterRecoveryComplete));
            }

            // Now ask the resource manager to reenlist.
            OletxEnlistment returnValue = oletxResourceManager.Reenlist(
                recoveryInformation.Length,
                recoveryInformation,
                enlistmentNotification
                );


            return(returnValue);
        }
コード例 #13
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();
        }
コード例 #14
0
        internal OletxEnlistment EnlistDurable(OletxTransaction oletxTransaction, bool canDoSinglePhase, IEnlistmentNotificationInternal enlistmentNotification, EnlistmentOptions enlistmentOptions)
        {
            IResourceManagerShim  resourceManagerShim = null;
            IPhase0EnlistmentShim shim2          = null;
            IEnlistmentShim       enlistmentShim = null;
            IntPtr          zero   = IntPtr.Zero;
            bool            flag3  = false;
            bool            flag2  = false;
            OletxEnlistment target = new OletxEnlistment(canDoSinglePhase, enlistmentNotification, oletxTransaction.RealTransaction.TxGuid, enlistmentOptions, this, oletxTransaction);
            bool            flag   = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                if ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None)
                {
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try
                    {
                    }
                    finally
                    {
                        oletxTransaction.RealTransaction.IncrementUndecidedEnlistments();
                        flag2 = true;
                    }
                }
                lock (target)
                {
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try
                    {
                        resourceManagerShim = this.ResourceManagerShim;
                        if (resourceManagerShim == null)
                        {
                            throw TransactionManagerCommunicationException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), null);
                        }
                        if ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None)
                        {
                            zero = HandleTable.AllocHandle(target);
                            RuntimeHelpers.PrepareConstrainedRegions();
                            try
                            {
                            }
                            finally
                            {
                                oletxTransaction.RealTransaction.TransactionShim.Phase0Enlist(zero, out shim2);
                                flag3 = true;
                            }
                            target.Phase0EnlistmentShim = shim2;
                        }
                        target.phase1Handle = HandleTable.AllocHandle(target);
                        resourceManagerShim.Enlist(oletxTransaction.RealTransaction.TransactionShim, target.phase1Handle, out enlistmentShim);
                        target.EnlistmentShim = enlistmentShim;
                    }
                    catch (COMException exception)
                    {
                        if (System.Transactions.Oletx.NativeMethods.XACT_E_TOOMANY_ENLISTMENTS == exception.ErrorCode)
                        {
                            throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("OletxTooManyEnlistments"), exception);
                        }
                        OletxTransactionManager.ProxyException(exception);
                        throw;
                    }
                    finally
                    {
                        if (target.EnlistmentShim == null)
                        {
                            if ((zero != IntPtr.Zero) && !flag3)
                            {
                                HandleTable.FreeHandle(zero);
                            }
                            if (target.phase1Handle != IntPtr.Zero)
                            {
                                HandleTable.FreeHandle(target.phase1Handle);
                            }
                        }
                    }
                }
                flag = true;
            }
            finally
            {
                if ((!flag && ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None)) && flag2)
                {
                    oletxTransaction.RealTransaction.DecrementUndecidedEnlistments();
                }
            }
            return(target);
        }
コード例 #15
0
        internal IPromotedEnlistment CommonEnlistVolatile(IEnlistmentNotificationInternal enlistmentNotification, EnlistmentOptions enlistmentOptions, OletxTransaction oletxTransaction)
        {
            OletxVolatileEnlistment enlistment = null;
            bool flag2 = false;
            bool flag  = false;
            OletxPhase0VolatileEnlistmentContainer target    = null;
            OletxPhase1VolatileEnlistmentContainer container = null;
            IntPtr                zero            = IntPtr.Zero;
            IVoterBallotShim      voterBallotShim = null;
            IPhase0EnlistmentShim shim            = null;
            bool flag3 = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                lock (this)
                {
                    enlistment = new OletxVolatileEnlistment(enlistmentNotification, enlistmentOptions, oletxTransaction);
                    if ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None)
                    {
                        if (this.phase0EnlistVolatilementContainerList == null)
                        {
                            this.phase0EnlistVolatilementContainerList = new ArrayList(1);
                        }
                        if (this.phase0EnlistVolatilementContainerList.Count == 0)
                        {
                            target = new OletxPhase0VolatileEnlistmentContainer(this);
                            flag   = true;
                        }
                        else
                        {
                            target = this.phase0EnlistVolatilementContainerList[this.phase0EnlistVolatilementContainerList.Count - 1] as OletxPhase0VolatileEnlistmentContainer;
                            if (!target.NewEnlistmentsAllowed)
                            {
                                target = new OletxPhase0VolatileEnlistmentContainer(this);
                                flag   = true;
                            }
                            else
                            {
                                flag = false;
                            }
                        }
                        if (flag)
                        {
                            zero = HandleTable.AllocHandle(target);
                        }
                    }
                    else if (this.phase1EnlistVolatilementContainer == null)
                    {
                        flag2     = true;
                        container = new OletxPhase1VolatileEnlistmentContainer(this)
                        {
                            voterHandle = HandleTable.AllocHandle(container)
                        };
                    }
                    else
                    {
                        flag2     = false;
                        container = this.phase1EnlistVolatilementContainer;
                    }
                    try
                    {
                        if (flag)
                        {
                            lock (target)
                            {
                                this.transactionShim.Phase0Enlist(zero, out shim);
                                target.Phase0EnlistmentShim = shim;
                            }
                        }
                        if (flag2)
                        {
                            this.transactionShim.CreateVoter(container.voterHandle, out voterBallotShim);
                            flag3 = true;
                            container.VoterBallotShim = voterBallotShim;
                        }
                        if ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None)
                        {
                            target.AddEnlistment(enlistment);
                            if (flag)
                            {
                                this.phase0EnlistVolatilementContainerList.Add(target);
                            }
                            return(enlistment);
                        }
                        container.AddEnlistment(enlistment);
                        if (flag2)
                        {
                            this.phase1EnlistVolatilementContainer = container;
                        }
                        return(enlistment);
                    }
                    catch (COMException exception)
                    {
                        OletxTransactionManager.ProxyException(exception);
                        throw;
                    }
                    return(enlistment);
                }
            }
            finally
            {
                if ((zero != IntPtr.Zero) && (target.Phase0EnlistmentShim == null))
                {
                    HandleTable.FreeHandle(zero);
                }
                if ((!flag3 && (container != null)) && ((container.voterHandle != IntPtr.Zero) && flag2))
                {
                    HandleTable.FreeHandle(container.voterHandle);
                }
            }
            return(enlistment);
        }
 internal void Prepare(OletxVolatileEnlistmentContainer container)
 {
     OletxVolatileEnlistmentState active = OletxVolatileEnlistmentState.Active;
     IEnlistmentNotificationInternal iEnlistmentNotification = null;
     lock (this)
     {
         iEnlistmentNotification = this.iEnlistmentNotification;
         if (this.state == OletxVolatileEnlistmentState.Active)
         {
             active = this.state = OletxVolatileEnlistmentState.Preparing;
         }
         else
         {
             active = this.state;
         }
         this.container = container;
     }
     if (OletxVolatileEnlistmentState.Preparing == active)
     {
         if (iEnlistmentNotification != null)
         {
             if (DiagnosticTrace.Verbose)
             {
                 EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Prepare);
             }
             iEnlistmentNotification.Prepare(this);
             return;
         }
         if (DiagnosticTrace.Critical)
         {
             InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
         }
         throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
     }
     if (OletxVolatileEnlistmentState.Done == active)
     {
         container.DecrementOutstandingNotifications(true);
     }
     else if ((OletxVolatileEnlistmentState.Prepared == active) && this.enlistDuringPrepareRequired)
     {
         container.DecrementOutstandingNotifications(true);
     }
     else if ((OletxVolatileEnlistmentState.Aborting == active) || (OletxVolatileEnlistmentState.Aborted == active))
     {
         container.DecrementOutstandingNotifications(false);
     }
     else
     {
         if (DiagnosticTrace.Critical)
         {
             InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "");
         }
         throw new InvalidOperationException(System.Transactions.SR.GetString("InternalError"));
     }
 }
コード例 #17
0
ファイル: OletxEnlistment.cs プロジェクト: JianwenSun/cc
        internal void FinishEnlistment()
        {
            lock ( this )
            {
                // If we don't have a wrappedTransactionEnlistmentAsync, we may
                // need to remove ourselves from the reenlistPendingList in the
                // resource manager.
                if ( null == this.enlistmentShim )
                {
                    oletxResourceManager.RemoveFromReenlistPending( this );
                }
                this.iEnlistmentNotification = null;

                RemoveFromEnlistmentTable();
            }
        }
コード例 #18
0
        internal OletxVolatileEnlistment(
            IEnlistmentNotificationInternal enlistmentNotification,
            EnlistmentOptions enlistmentOptions,
            OletxTransaction oletxTransaction
            ) : base( null, oletxTransaction )
        {
            this.iEnlistmentNotification = enlistmentNotification;
            this.enlistDuringPrepareRequired = (enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != 0;

            // We get a container when we are asked to vote.
            this.container = null;

            pendingOutcome = TransactionStatus.Active;

            if ( DiagnosticTrace.Information )
            {
                EnlistmentTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    this.InternalTraceIdentifier,
                    EnlistmentType.Volatile,
                    enlistmentOptions
                    );
            }
        }
コード例 #19
0
        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 IPromotedEnlistment EnlistVolatile(IEnlistmentNotificationInternal enlistmentNotification, EnlistmentOptions enlistmentOptions, OletxTransaction oletxTransaction)
 {
     return this.CommonEnlistVolatile(enlistmentNotification, enlistmentOptions, oletxTransaction);
 }
コード例 #21
0
        internal OletxEnlistment ReenlistTransaction(
            Guid resourceManagerIdentifier,
            byte[] recoveryInformation,
            IEnlistmentNotificationInternal enlistmentNotification
            )
        {
            if ( null == recoveryInformation )
            {
                throw new ArgumentNullException( "recoveryInformation" );
            }

            if ( null == enlistmentNotification )
            {
                throw new ArgumentNullException( "enlistmentNotification" );
            }

            // Now go find the resource manager in the collection.
            OletxResourceManager oletxResourceManager = RegisterResourceManager( resourceManagerIdentifier );
            if ( null == oletxResourceManager )
            {
                throw new ArgumentException( SR.GetString( SR.InvalidArgument ), "resourceManagerIdentifier" );
            }
            
            if ( oletxResourceManager.RecoveryCompleteCalledByApplication )
            {
                throw new InvalidOperationException( SR.GetString( SR.ReenlistAfterRecoveryComplete ));
            }

            // Now ask the resource manager to reenlist.
            OletxEnlistment returnValue = oletxResourceManager.Reenlist(
                recoveryInformation.Length,
                recoveryInformation,
                enlistmentNotification
                );


            return returnValue;
        }
コード例 #22
0
ファイル: OleTxTransaction.cs プロジェクト: mind0n/hive
        internal IPromotedEnlistment CommonEnlistVolatile(
            IEnlistmentNotificationInternal enlistmentNotification,
            EnlistmentOptions enlistmentOptions,
            OletxTransaction oletxTransaction
            )
        {
            OletxVolatileEnlistment enlistment = null;
            bool needVoterEnlistment = false;
            bool needPhase0Enlistment = false;
            OletxPhase0VolatileEnlistmentContainer localPhase0VolatileContainer = null;
            OletxPhase1VolatileEnlistmentContainer localPhase1VolatileContainer = null;
            IntPtr phase0Handle = IntPtr.Zero;
            IVoterBallotShim voterShim = null;
            IPhase0EnlistmentShim phase0Shim = null;
            bool enlistmentSucceeded = false;

            // Yes, we are talking to the proxy while holding the lock on the RealOletxTransaction.
            // If we don't then things get real sticky with other threads allocating containers.
            // We only do this the first time we get a depenent clone of a given type (delay vs. non-delay).
            // After that, we don't create a new container, except for Phase0 if we need to create one
            // for a second wave.
            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                lock ( this )
                {
                    enlistment = new OletxVolatileEnlistment(
                        enlistmentNotification,
                        enlistmentOptions,
                        oletxTransaction
                        );

                    if ( (enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != 0 )
                    {
                        if ( null == this.phase0EnlistVolatilementContainerList )
                        {
                            // Not using a MemoryBarrier because all access to this member variable is done when holding
                            // a lock on the object.
                            this.phase0EnlistVolatilementContainerList = new ArrayList(1);
                        }
                        // We may have failed the proxy enlistment for the first container, but we would have
                        // allocated the list.  That is why we have this check here.
                        if ( 0 == this.phase0EnlistVolatilementContainerList.Count )
                        {
                            localPhase0VolatileContainer = new OletxPhase0VolatileEnlistmentContainer( this );
                            needPhase0Enlistment = true;
                        }
                        else
                        {
                            localPhase0VolatileContainer = this.phase0EnlistVolatilementContainerList[this.phase0EnlistVolatilementContainerList.Count - 1] as OletxPhase0VolatileEnlistmentContainer;
                            if ( ! localPhase0VolatileContainer.NewEnlistmentsAllowed )
                            {
                                localPhase0VolatileContainer = new OletxPhase0VolatileEnlistmentContainer( this );
                                needPhase0Enlistment = true;
                            }
                            else
                            {
                                needPhase0Enlistment = false;
                            }
                        }

                        if ( needPhase0Enlistment )
                        {
                            // We need to create a VoterNotifyShim if native threads are not allowed to enter managed code.
                            phase0Handle = HandleTable.AllocHandle( localPhase0VolatileContainer );
                        }
                    }
                    else  // not EDPR = TRUE - may need a voter... 
                    {
                        if ( null == this.phase1EnlistVolatilementContainer )
                        {
                            needVoterEnlistment = true;
                            localPhase1VolatileContainer = new OletxPhase1VolatileEnlistmentContainer( this );

                            // We need to create a VoterNotifyShim.
                            localPhase1VolatileContainer.voterHandle = 
                                HandleTable.AllocHandle( localPhase1VolatileContainer );
                        }
                        else
                        {
                            needVoterEnlistment = false;
                            localPhase1VolatileContainer = this.phase1EnlistVolatilementContainer;
                        }
                    }


                    try
                    {
                        // If enlistDuringPrepareRequired is true, we need to ask the proxy to create a Phase0 enlistment.
                        if ( needPhase0Enlistment )
                        {
                            lock ( localPhase0VolatileContainer )
                            {
                                transactionShim.Phase0Enlist(
                                    phase0Handle,
                                    out phase0Shim );

                                localPhase0VolatileContainer.Phase0EnlistmentShim = phase0Shim;
                            }

                        }

                        if ( needVoterEnlistment )
                        {
                            this.transactionShim.CreateVoter(
                                localPhase1VolatileContainer.voterHandle,
                                out voterShim );

                            enlistmentSucceeded = true;
                            localPhase1VolatileContainer.VoterBallotShim = voterShim;
                        }
                
                        if ( (enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != 0 )
                        {
                            localPhase0VolatileContainer.AddEnlistment(
                                enlistment
                                );
                            if ( needPhase0Enlistment )
                            {
                                this.phase0EnlistVolatilementContainerList.Add( localPhase0VolatileContainer );
                            }
                        }
                        else
                        {
                            localPhase1VolatileContainer.AddEnlistment(
                                enlistment
                                );

                            if ( needVoterEnlistment )
                            {
                                Debug.Assert( ( null == this.phase1EnlistVolatilementContainer ),
                                    "RealOletxTransaction.CommonEnlistVolatile - phase1VolContainer not null when expected." );
                                this.phase1EnlistVolatilementContainer = localPhase1VolatileContainer;
                            }
                        }
                    }
                    catch (COMException comException)
                    {
                        OletxTransactionManager.ProxyException( comException );
                        throw;
                    }
                }
            }
            finally
            {
                if ( phase0Handle != IntPtr.Zero && localPhase0VolatileContainer.Phase0EnlistmentShim == null )
                {
                    HandleTable.FreeHandle( phase0Handle );
                }

                if ( !enlistmentSucceeded && 
                    null != localPhase1VolatileContainer && 
                    localPhase1VolatileContainer.voterHandle != IntPtr.Zero &&
                    needVoterEnlistment )
                {
                    HandleTable.FreeHandle( localPhase1VolatileContainer.voterHandle );
                }
            }

            return enlistment;
        }
コード例 #23
0
ファイル: OletxEnlistment.cs プロジェクト: mikem8361/runtime
    internal OletxEnlistment(
        IEnlistmentNotificationInternal enlistmentNotification,
        OletxTransactionStatus xactStatus,
        byte[] prepareInfoByteArray,
        OletxResourceManager oletxResourceManager)
        : base(oletxResourceManager, null)
    {
        // This will get set later by the creator of this object after it
        // has enlisted with the proxy.
        EnlistmentShim = null;
        _phase0Shim    = null;

        _canDoSinglePhase        = false;
        _iEnlistmentNotification = enlistmentNotification;
        State = OletxEnlistmentState.Active;

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

        int prepareInfoLength = prepareInfoByteArray.Length;

        _proxyPrepareInfoByteArray = new byte[prepareInfoLength];
        Array.Copy(prepareInfoByteArray, _proxyPrepareInfoByteArray, prepareInfoLength);

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

        _transactionGuid      = new Guid(txGuidByteArray);
        TransactionGuidString = _transactionGuid.ToString();

        TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

        // 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:
        {
            State = OletxEnlistmentState.Aborting;
            if (etwLog.IsEnabled())
            {
                etwLog.EnlistmentStatus(TraceSourceType.TraceSourceOleTx, InternalTraceIdentifier, NotificationCall.Rollback);
            }

            _iEnlistmentNotification.Rollback(this);
            break;
        }

        case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_COMMITTED:
        {
            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 (etwLog.IsEnabled())
            {
                etwLog.EnlistmentStatus(TraceSourceType.TraceSourceOleTx, InternalTraceIdentifier, NotificationCall.Commit);
            }

            _iEnlistmentNotification.Commit(this);
            break;
        }

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

        default:
        {
            if (etwLog.IsEnabled())
            {
                etwLog.InternalError(SR.OletxEnlistmentUnexpectedTransactionStatus);
            }

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

        if (etwLog.IsEnabled())
        {
            etwLog.EnlistmentCreated(TraceSourceType.TraceSourceOleTx, InternalTraceIdentifier, EnlistmentType.Durable, EnlistmentOptions.None);
        }

        // Always do this last in case anything prior to this fails.
        AddToEnlistmentTable();
    }
コード例 #24
0
ファイル: OletxResourceManager.cs プロジェクト: JianwenSun/cc
        internal OletxEnlistment EnlistDurable(
            OletxTransaction oletxTransaction,
            bool canDoSinglePhase,
            IEnlistmentNotificationInternal enlistmentNotification,
            EnlistmentOptions enlistmentOptions
            )
        {
            IResourceManagerShim localResourceManagerShim = null;

            Debug.Assert( null != oletxTransaction, "Argument is null" );
            Debug.Assert( null != enlistmentNotification, "Argument is null" );

            IEnlistmentShim enlistmentShim = null;
            IPhase0EnlistmentShim phase0Shim = null;
            Guid txUow = Guid.Empty;
            IntPtr handlePhase0 = IntPtr.Zero;
            bool phase0EnlistSucceeded = false;
            bool undecidedEnlistmentsIncremented = false;

            // Create our enlistment object.
            OletxEnlistment enlistment = new OletxEnlistment(
                canDoSinglePhase,
                enlistmentNotification,
                oletxTransaction.RealTransaction.TxGuid,
                enlistmentOptions,
                this,
                oletxTransaction
                );

            bool enlistmentSucceeded = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                if ( (enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != 0 )
                {
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try { }
                    finally
                    {                    
                        oletxTransaction.RealTransaction.IncrementUndecidedEnlistments();
                        undecidedEnlistmentsIncremented = true;
                    }
                }

                // This entire sequense needs to be executed before we can go on.
                lock ( enlistment )
                {
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try
                    {
                        // Do the enlistment on the proxy.
                        localResourceManagerShim = this.ResourceManagerShim;
                        if ( null == localResourceManagerShim )
                        {
                            // The TM must be down.  Throw the appropriate exception.
                            throw TransactionManagerCommunicationException.Create( SR.GetString( SR.TraceSourceOletx),  null );
                        }
                        
                        if ( (enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != 0 )
                        {
                            // We need to create an EnlistmentNotifyShim if native threads are not allowed to enter managed code.
                            handlePhase0 = HandleTable.AllocHandle( enlistment );

                            RuntimeHelpers.PrepareConstrainedRegions();
                            try { }
                            finally
                            {
                                oletxTransaction.RealTransaction.TransactionShim.Phase0Enlist(
                                    handlePhase0,
                                    out phase0Shim );
                                phase0EnlistSucceeded = true;
                            }
                            enlistment.Phase0EnlistmentShim = phase0Shim;
                        }

                        enlistment.phase1Handle = HandleTable.AllocHandle( enlistment );
                        localResourceManagerShim.Enlist(
                            oletxTransaction.RealTransaction.TransactionShim,
                            enlistment.phase1Handle,
                            out enlistmentShim );

                        enlistment.EnlistmentShim = enlistmentShim;
                    }
                    catch (COMException comException)
                    {
                        // There is no string mapping for XACT_E_TOOMANY_ENLISTMENTS, so we need to do it here.
                        if ( NativeMethods.XACT_E_TOOMANY_ENLISTMENTS == comException.ErrorCode )
                        {
                            throw TransactionException.Create(
                                SR.GetString( SR.TraceSourceOletx ),
                                SR.GetString( SR.OletxTooManyEnlistments ),
                                comException );
                        }

                        OletxTransactionManager.ProxyException( comException );

                        throw;
                    }
                    finally
                    {
                        if ( enlistment.EnlistmentShim == null )
                        {
                            // If the enlistment shim was never assigned then something blew up.
                            // Perform some cleanup.
                            if ( handlePhase0 != IntPtr.Zero && !phase0EnlistSucceeded )
                            {
                                // Only clean up the phase0 handle if the phase 0 enlistment did not succeed.
                                // This is because the notification processing code expects it to exist.
                                HandleTable.FreeHandle( handlePhase0 );
                            }

                            if ( enlistment.phase1Handle != IntPtr.Zero )
                            {
                                HandleTable.FreeHandle( enlistment.phase1Handle );
                            }

                            // Note this code used to call unenlist however this allows race conditions where
                            // it is unclear if the handlePhase0 should be freed or not.  The notification
                            // thread should get a phase0Request and it will free the Handle at that point.
                        }
                    }
                }

                enlistmentSucceeded = true;
            }
            finally
            {
                if ( !enlistmentSucceeded &&
                    ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != 0) && 
                    undecidedEnlistmentsIncremented )
                {
                    oletxTransaction.RealTransaction.DecrementUndecidedEnlistments();
                }
            }

            return enlistment;
        }
コード例 #25
0
ファイル: OletxResourceManager.cs プロジェクト: JianwenSun/cc
        internal OletxEnlistment Reenlist(
            int prepareInfoLength,
            byte[] prepareInfo,
            IEnlistmentNotificationInternal enlistmentNotification
            )
        {
            OletxTransactionOutcome outcome = OletxTransactionOutcome.NotKnownYet;
            OletxTransactionStatus xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_NONE;

            // Put the recovery information into a stream.
            MemoryStream stream = new MemoryStream( prepareInfo );

            // First extract the OletxRecoveryInformation from the stream.
            IFormatter formatter = new BinaryFormatter();
            OletxRecoveryInformation oletxRecoveryInformation;
            try
            {
                oletxRecoveryInformation = formatter.Deserialize( stream ) as OletxRecoveryInformation;
            }
            catch (SerializationException se)
            {
                throw new ArgumentException( SR.GetString( SR.InvalidArgument ), "prepareInfo", se );
            }
            
            if ( null == oletxRecoveryInformation )
            {
                throw new ArgumentException( SR.GetString( SR.InvalidArgument ), "prepareInfo" );
            }

            // Verify that the resource manager guid in the recovery info matches that of the calling resource manager.
            byte[] rmGuidArray = new byte[16];
            for ( int i = 0; i < 16; i++ )
            {
                rmGuidArray[i] = oletxRecoveryInformation.proxyRecoveryInformation[i + 16];
            }
            Guid rmGuid = new Guid( rmGuidArray );
            if ( rmGuid != this.resourceManagerIdentifier )
            {
                throw TransactionException.Create( SR.GetString( SR.TraceSourceOletx ), SR.GetString( SR.ResourceManagerIdDoesNotMatchRecoveryInformation ), null );
            }

            // Ask the proxy resource manager to reenlist.
            IResourceManagerShim localResourceManagerShim = null;
            try
            {
                localResourceManagerShim = this.ResourceManagerShim;
                if ( null == localResourceManagerShim )
                {
                    // The TM must be down.  Throw the exception that will get caught below and will cause
                    // the enlistment to start the ReenlistThread.  The TMDown thread will be trying to reestablish
                    // connection with the TM and will start the reenlist thread when it does.
                    throw new COMException( SR.GetString( SR.DtcTransactionManagerUnavailable ), NativeMethods.XACT_E_CONNECTION_DOWN );
                }

                // Only wait for 5 milliseconds.  If the TM doesn't have the outcome now, we will
                // put the enlistment on the reenlistList for later processing.
                localResourceManagerShim.Reenlist(
                    Convert.ToUInt32( oletxRecoveryInformation.proxyRecoveryInformation.Length, CultureInfo.InvariantCulture ),
                    oletxRecoveryInformation.proxyRecoveryInformation,
                    out outcome
                    );

                if ( OletxTransactionOutcome.Committed == outcome )
                {
                    xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_COMMITTED;
                }
                else if ( OletxTransactionOutcome.Aborted == outcome )
                {
                    xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_ABORTED;
                }
                else  // we must not know the outcome yet.
                {
                    xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED;
                    StartReenlistThread();
                }
            }
            catch ( COMException ex )
            {
                if ( NativeMethods.XACT_E_CONNECTION_DOWN == ex.ErrorCode )
                {
                    xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED;
                    this.ResourceManagerShim = null;
                    StartReenlistThread();
                    if ( DiagnosticTrace.Verbose )
                    {
                        ExceptionConsumedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            ex );
                    }

                }
                else
                {
                    throw;
                }
            }
            finally
            {
                localResourceManagerShim = null;
            }

            // Now create our enlistment to tell the client the outcome.
            OletxEnlistment enlistment = new OletxEnlistment(
                enlistmentNotification,
                xactStatus,
                oletxRecoveryInformation.proxyRecoveryInformation,
                this
                );

            return enlistment;
        }
コード例 #26
0
        internal OletxEnlistment Reenlist(int prepareInfoLength, byte[] prepareInfo, IEnlistmentNotificationInternal enlistmentNotification)
        {
            OletxRecoveryInformation information;
            OletxTransactionOutcome  notKnownYet         = OletxTransactionOutcome.NotKnownYet;
            OletxTransactionStatus   xactStatus          = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_NONE;
            MemoryStream             serializationStream = new MemoryStream(prepareInfo);
            IFormatter formatter = new BinaryFormatter();

            try
            {
                information = formatter.Deserialize(serializationStream) as OletxRecoveryInformation;
            }
            catch (SerializationException exception2)
            {
                throw new ArgumentException(System.Transactions.SR.GetString("InvalidArgument"), "prepareInfo", exception2);
            }
            if (information == null)
            {
                throw new ArgumentException(System.Transactions.SR.GetString("InvalidArgument"), "prepareInfo");
            }
            byte[] b = new byte[0x10];
            for (int i = 0; i < 0x10; i++)
            {
                b[i] = information.proxyRecoveryInformation[i + 0x10];
            }
            Guid guid = new Guid(b);

            if (guid != this.resourceManagerIdentifier)
            {
                throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("ResourceManagerIdDoesNotMatchRecoveryInformation"), null);
            }
            IResourceManagerShim resourceManagerShim = null;

            try
            {
                resourceManagerShim = this.ResourceManagerShim;
                if (resourceManagerShim == null)
                {
                    throw new COMException(System.Transactions.SR.GetString("DtcTransactionManagerUnavailable"), System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN);
                }
                resourceManagerShim.Reenlist(Convert.ToUInt32(information.proxyRecoveryInformation.Length, CultureInfo.InvariantCulture), information.proxyRecoveryInformation, out notKnownYet);
                if (OletxTransactionOutcome.Committed == notKnownYet)
                {
                    xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_COMMITTED;
                }
                else if (OletxTransactionOutcome.Aborted == notKnownYet)
                {
                    xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_ABORTED;
                }
                else
                {
                    xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED;
                    this.StartReenlistThread();
                }
            }
            catch (COMException exception)
            {
                if (System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN != exception.ErrorCode)
                {
                    throw;
                }
                xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED;
                this.ResourceManagerShim = null;
                this.StartReenlistThread();
                if (DiagnosticTrace.Verbose)
                {
                    ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
                }
            }
            finally
            {
                resourceManagerShim = null;
            }
            return(new OletxEnlistment(enlistmentNotification, xactStatus, information.proxyRecoveryInformation, this));
        }
 internal OletxEnlistment ReenlistTransaction(Guid resourceManagerIdentifier, byte[] recoveryInformation, IEnlistmentNotificationInternal enlistmentNotification)
 {
     if (recoveryInformation == null)
     {
         throw new ArgumentNullException("recoveryInformation");
     }
     if (enlistmentNotification == null)
     {
         throw new ArgumentNullException("enlistmentNotification");
     }
     OletxResourceManager manager = this.RegisterResourceManager(resourceManagerIdentifier);
     if (manager == null)
     {
         throw new ArgumentException(System.Transactions.SR.GetString("InvalidArgument"), "resourceManagerIdentifier");
     }
     if (manager.RecoveryCompleteCalledByApplication)
     {
         throw new InvalidOperationException(System.Transactions.SR.GetString("ReenlistAfterRecoveryComplete"));
     }
     return manager.Reenlist(recoveryInformation.Length, recoveryInformation, enlistmentNotification);
 }
コード例 #28
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");
            }
        }
コード例 #29
0
    internal OletxEnlistment Reenlist(byte[] prepareInfo, IEnlistmentNotificationInternal enlistmentNotification)
    {
        OletxTransactionOutcome outcome    = OletxTransactionOutcome.NotKnownYet;
        OletxTransactionStatus  xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_NONE;

        if (prepareInfo == null)
        {
            throw new ArgumentException(SR.InvalidArgument, nameof(prepareInfo));
        }

        // Verify that the resource manager guid in the recovery info matches that of the calling resource manager.
        byte[] rmGuidArray = new byte[16];
        for (int i = 0; i < 16; i++)
        {
            rmGuidArray[i] = prepareInfo[i + 16];
        }
        Guid rmGuid = new(rmGuidArray);

        if (rmGuid != ResourceManagerIdentifier)
        {
            throw TransactionException.Create(TraceSourceType.TraceSourceOleTx, SR.ResourceManagerIdDoesNotMatchRecoveryInformation, null);
        }

        // Ask the proxy resource manager to reenlist.
        ResourceManagerShim?localResourceManagerShim = null;

        try
        {
            localResourceManagerShim = ResourceManagerShim;
            if (localResourceManagerShim == null)
            {
                // The TM must be down.  Throw the exception that will get caught below and will cause
                // the enlistment to start the ReenlistThread.  The TMDown thread will be trying to reestablish
                // connection with the TM and will start the reenlist thread when it does.
                throw new COMException(SR.DtcTransactionManagerUnavailable, OletxHelper.XACT_E_CONNECTION_DOWN);
            }

            // Only wait for 5 milliseconds.  If the TM doesn't have the outcome now, we will
            // put the enlistment on the reenlistList for later processing.
            localResourceManagerShim.Reenlist(prepareInfo, out outcome);

            if (OletxTransactionOutcome.Committed == outcome)
            {
                xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_COMMITTED;
            }
            else if (OletxTransactionOutcome.Aborted == outcome)
            {
                xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_ABORTED;
            }
            else  // we must not know the outcome yet.
            {
                xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED;
                StartReenlistThread();
            }
        }
        catch (COMException ex) when(ex.ErrorCode == OletxHelper.XACT_E_CONNECTION_DOWN)
        {
            xactStatus          = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED;
            ResourceManagerShim = null;
            StartReenlistThread();

            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.ExceptionConsumed(TraceSourceType.TraceSourceOleTx, ex);
            }
        }
        finally
        {
            localResourceManagerShim = null;
        }

        // Now create our enlistment to tell the client the outcome.
        return(new OletxEnlistment(enlistmentNotification, xactStatus, prepareInfo, this));
    }
 internal OletxEnlistment EnlistDurable(OletxTransaction oletxTransaction, bool canDoSinglePhase, IEnlistmentNotificationInternal enlistmentNotification, EnlistmentOptions enlistmentOptions)
 {
     IResourceManagerShim resourceManagerShim = null;
     IPhase0EnlistmentShim shim2 = null;
     IEnlistmentShim enlistmentShim = null;
     IntPtr zero = IntPtr.Zero;
     bool flag3 = false;
     bool flag2 = false;
     OletxEnlistment target = new OletxEnlistment(canDoSinglePhase, enlistmentNotification, oletxTransaction.RealTransaction.TxGuid, enlistmentOptions, this, oletxTransaction);
     bool flag = false;
     RuntimeHelpers.PrepareConstrainedRegions();
     try
     {
         if ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None)
         {
             RuntimeHelpers.PrepareConstrainedRegions();
             try
             {
             }
             finally
             {
                 oletxTransaction.RealTransaction.IncrementUndecidedEnlistments();
                 flag2 = true;
             }
         }
         lock (target)
         {
             RuntimeHelpers.PrepareConstrainedRegions();
             try
             {
                 resourceManagerShim = this.ResourceManagerShim;
                 if (resourceManagerShim == null)
                 {
                     throw TransactionManagerCommunicationException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), null);
                 }
                 if ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None)
                 {
                     zero = HandleTable.AllocHandle(target);
                     RuntimeHelpers.PrepareConstrainedRegions();
                     try
                     {
                     }
                     finally
                     {
                         oletxTransaction.RealTransaction.TransactionShim.Phase0Enlist(zero, out shim2);
                         flag3 = true;
                     }
                     target.Phase0EnlistmentShim = shim2;
                 }
                 target.phase1Handle = HandleTable.AllocHandle(target);
                 resourceManagerShim.Enlist(oletxTransaction.RealTransaction.TransactionShim, target.phase1Handle, out enlistmentShim);
                 target.EnlistmentShim = enlistmentShim;
             }
             catch (COMException exception)
             {
                 if (System.Transactions.Oletx.NativeMethods.XACT_E_TOOMANY_ENLISTMENTS == exception.ErrorCode)
                 {
                     throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("OletxTooManyEnlistments"), exception);
                 }
                 OletxTransactionManager.ProxyException(exception);
                 throw;
             }
             finally
             {
                 if (target.EnlistmentShim == null)
                 {
                     if ((zero != IntPtr.Zero) && !flag3)
                     {
                         HandleTable.FreeHandle(zero);
                     }
                     if (target.phase1Handle != IntPtr.Zero)
                     {
                         HandleTable.FreeHandle(target.phase1Handle);
                     }
                 }
             }
         }
         flag = true;
     }
     finally
     {
         if ((!flag && ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None)) && flag2)
         {
             oletxTransaction.RealTransaction.DecrementUndecidedEnlistments();
         }
     }
     return target;
 }
コード例 #31
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");
     }
 }
コード例 #32
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();
        }
コード例 #33
0
 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 Reenlist(int prepareInfoLength, byte[] prepareInfo, IEnlistmentNotificationInternal enlistmentNotification)
 {
     OletxRecoveryInformation information;
     OletxTransactionOutcome notKnownYet = OletxTransactionOutcome.NotKnownYet;
     OletxTransactionStatus xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_NONE;
     MemoryStream serializationStream = new MemoryStream(prepareInfo);
     IFormatter formatter = new BinaryFormatter();
     try
     {
         information = formatter.Deserialize(serializationStream) as OletxRecoveryInformation;
     }
     catch (SerializationException exception2)
     {
         throw new ArgumentException(System.Transactions.SR.GetString("InvalidArgument"), "prepareInfo", exception2);
     }
     if (information == null)
     {
         throw new ArgumentException(System.Transactions.SR.GetString("InvalidArgument"), "prepareInfo");
     }
     byte[] b = new byte[0x10];
     for (int i = 0; i < 0x10; i++)
     {
         b[i] = information.proxyRecoveryInformation[i + 0x10];
     }
     Guid guid = new Guid(b);
     if (guid != this.resourceManagerIdentifier)
     {
         throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("ResourceManagerIdDoesNotMatchRecoveryInformation"), null);
     }
     IResourceManagerShim resourceManagerShim = null;
     try
     {
         resourceManagerShim = this.ResourceManagerShim;
         if (resourceManagerShim == null)
         {
             throw new COMException(System.Transactions.SR.GetString("DtcTransactionManagerUnavailable"), System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN);
         }
         resourceManagerShim.Reenlist(Convert.ToUInt32(information.proxyRecoveryInformation.Length, CultureInfo.InvariantCulture), information.proxyRecoveryInformation, out notKnownYet);
         if (OletxTransactionOutcome.Committed == notKnownYet)
         {
             xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_COMMITTED;
         }
         else if (OletxTransactionOutcome.Aborted == notKnownYet)
         {
             xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_ABORTED;
         }
         else
         {
             xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED;
             this.StartReenlistThread();
         }
     }
     catch (COMException exception)
     {
         if (System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN != exception.ErrorCode)
         {
             throw;
         }
         xactStatus = OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED;
         this.ResourceManagerShim = null;
         this.StartReenlistThread();
         if (DiagnosticTrace.Verbose)
         {
             ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
         }
     }
     finally
     {
         resourceManagerShim = null;
     }
     return new OletxEnlistment(enlistmentNotification, xactStatus, information.proxyRecoveryInformation, this);
 }
コード例 #35
0
 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();
 }
コード例 #36
0
ファイル: OleTxTransaction.cs プロジェクト: mind0n/hive
        internal IPromotedEnlistment EnlistVolatile(
            IEnlistmentNotificationInternal enlistmentNotification,
            EnlistmentOptions enlistmentOptions
            )
        {
            if ( DiagnosticTrace.Verbose )
            {
                MethodEnteredTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "OletxTransaction.EnlistVolatile( IEnlistmentNotificationInternal )"
                    );
            }

            Debug.Assert( null != enlistmentNotification, "Argument is null" );
            Debug.Assert( ( 0 == this.disposed ), "OletxTransction object is disposed" );

            if ( this.realOletxTransaction == null || this.realOletxTransaction.TooLateForEnlistments )
            {
                throw TransactionException.Create(SR.GetString(SR.TraceSourceOletx),
                    SR.GetString(SR.TooLate), null, this.DistributedTxId);
            }

            IPromotedEnlistment enlistment = realOletxTransaction.EnlistVolatile(
                enlistmentNotification,
                enlistmentOptions,
                this
                );

            if ( DiagnosticTrace.Verbose )
            {
                MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "OletxTransaction.EnlistVolatile( IEnlistmentNotificationInternal )"
                    );
            }
            return enlistment;
        }
コード例 #37
0
 internal IPromotedEnlistment EnlistVolatile(IEnlistmentNotificationInternal enlistmentNotification, EnlistmentOptions enlistmentOptions, OletxTransaction oletxTransaction)
 {
     return(this.CommonEnlistVolatile(enlistmentNotification, enlistmentOptions, oletxTransaction));
 }
 internal IPromotedEnlistment CommonEnlistVolatile(IEnlistmentNotificationInternal enlistmentNotification, EnlistmentOptions enlistmentOptions, OletxTransaction oletxTransaction)
 {
     OletxVolatileEnlistment enlistment = null;
     bool flag2 = false;
     bool flag = false;
     OletxPhase0VolatileEnlistmentContainer target = null;
     OletxPhase1VolatileEnlistmentContainer container = null;
     IntPtr zero = IntPtr.Zero;
     IVoterBallotShim voterBallotShim = null;
     IPhase0EnlistmentShim shim = null;
     bool flag3 = false;
     RuntimeHelpers.PrepareConstrainedRegions();
     try
     {
         lock (this)
         {
             enlistment = new OletxVolatileEnlistment(enlistmentNotification, enlistmentOptions, oletxTransaction);
             if ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None)
             {
                 if (this.phase0EnlistVolatilementContainerList == null)
                 {
                     this.phase0EnlistVolatilementContainerList = new ArrayList(1);
                 }
                 if (this.phase0EnlistVolatilementContainerList.Count == 0)
                 {
                     target = new OletxPhase0VolatileEnlistmentContainer(this);
                     flag = true;
                 }
                 else
                 {
                     target = this.phase0EnlistVolatilementContainerList[this.phase0EnlistVolatilementContainerList.Count - 1] as OletxPhase0VolatileEnlistmentContainer;
                     if (!target.NewEnlistmentsAllowed)
                     {
                         target = new OletxPhase0VolatileEnlistmentContainer(this);
                         flag = true;
                     }
                     else
                     {
                         flag = false;
                     }
                 }
                 if (flag)
                 {
                     zero = HandleTable.AllocHandle(target);
                 }
             }
             else if (this.phase1EnlistVolatilementContainer == null)
             {
                 flag2 = true;
                 container = new OletxPhase1VolatileEnlistmentContainer(this) {
                     voterHandle = HandleTable.AllocHandle(container)
                 };
             }
             else
             {
                 flag2 = false;
                 container = this.phase1EnlistVolatilementContainer;
             }
             try
             {
                 if (flag)
                 {
                     lock (target)
                     {
                         this.transactionShim.Phase0Enlist(zero, out shim);
                         target.Phase0EnlistmentShim = shim;
                     }
                 }
                 if (flag2)
                 {
                     this.transactionShim.CreateVoter(container.voterHandle, out voterBallotShim);
                     flag3 = true;
                     container.VoterBallotShim = voterBallotShim;
                 }
                 if ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None)
                 {
                     target.AddEnlistment(enlistment);
                     if (flag)
                     {
                         this.phase0EnlistVolatilementContainerList.Add(target);
                     }
                     return enlistment;
                 }
                 container.AddEnlistment(enlistment);
                 if (flag2)
                 {
                     this.phase1EnlistVolatilementContainer = container;
                 }
                 return enlistment;
             }
             catch (COMException exception)
             {
                 OletxTransactionManager.ProxyException(exception);
                 throw;
             }
             return enlistment;
         }
     }
     finally
     {
         if ((zero != IntPtr.Zero) && (target.Phase0EnlistmentShim == null))
         {
             HandleTable.FreeHandle(zero);
         }
         if ((!flag3 && (container != null)) && ((container.voterHandle != IntPtr.Zero) && flag2))
         {
             HandleTable.FreeHandle(container.voterHandle);
         }
     }
     return enlistment;
 }
コード例 #39
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();
             }
         }
     }
 }
コード例 #40
0
        internal OletxEnlistment ReenlistTransaction(Guid resourceManagerIdentifier, byte[] recoveryInformation, IEnlistmentNotificationInternal enlistmentNotification)
        {
            if (recoveryInformation == null)
            {
                throw new ArgumentNullException("recoveryInformation");
            }
            if (enlistmentNotification == null)
            {
                throw new ArgumentNullException("enlistmentNotification");
            }
            OletxResourceManager manager = this.RegisterResourceManager(resourceManagerIdentifier);

            if (manager == null)
            {
                throw new ArgumentException(System.Transactions.SR.GetString("InvalidArgument"), "resourceManagerIdentifier");
            }
            if (manager.RecoveryCompleteCalledByApplication)
            {
                throw new InvalidOperationException(System.Transactions.SR.GetString("ReenlistAfterRecoveryComplete"));
            }
            return(manager.Reenlist(recoveryInformation.Length, recoveryInformation, enlistmentNotification));
        }
コード例 #41
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();
        }
コード例 #42
0
 internal void FinishEnlistment()
 {
     lock (this)
     {
         if (this.enlistmentShim == null)
         {
             base.oletxResourceManager.RemoveFromReenlistPending(this);
         }
         this.iEnlistmentNotification = null;
         base.RemoveFromEnlistmentTable();
     }
 }
コード例 #43
0
    internal OletxEnlistment EnlistDurable(
        OletxTransaction oletxTransaction,
        bool canDoSinglePhase,
        IEnlistmentNotificationInternal enlistmentNotification,
        EnlistmentOptions enlistmentOptions)
    {
        ResourceManagerShim?localResourceManagerShim;

        Debug.Assert(oletxTransaction != null, "Argument is null");
        Debug.Assert(enlistmentNotification != null, "Argument is null");

        EnlistmentShim       enlistmentShim;
        Phase0EnlistmentShim phase0Shim;
        Guid txUow = Guid.Empty;
        bool undecidedEnlistmentsIncremented = false;

        // Create our enlistment object.
        OletxEnlistment enlistment = new(
            canDoSinglePhase,
            enlistmentNotification,
            oletxTransaction.RealTransaction.TxGuid,
            enlistmentOptions,
            this,
            oletxTransaction);

        bool enlistmentSucceeded = false;

        try
        {
            if ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != 0)
            {
                oletxTransaction.RealTransaction.IncrementUndecidedEnlistments();
                undecidedEnlistmentsIncremented = true;
            }

            // This entire sequence needs to be executed before we can go on.
            lock (enlistment)
            {
                try
                {
                    // Do the enlistment on the proxy.
                    localResourceManagerShim = ResourceManagerShim;
                    if (localResourceManagerShim == null)
                    {
                        // The TM must be down.  Throw the appropriate exception.
                        throw TransactionManagerCommunicationException.Create(SR.TraceSourceOletx, null);
                    }

                    if ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != 0)
                    {
                        oletxTransaction.RealTransaction.TransactionShim.Phase0Enlist(enlistment, out phase0Shim);
                        enlistment.Phase0EnlistmentShim = phase0Shim;
                    }

                    localResourceManagerShim.Enlist(oletxTransaction.RealTransaction.TransactionShim, enlistment, out enlistmentShim);

                    enlistment.EnlistmentShim = enlistmentShim;
                }
                catch (COMException comException)
                {
                    // There is no string mapping for XACT_E_TOOMANY_ENLISTMENTS, so we need to do it here.
                    if (comException.ErrorCode == OletxHelper.XACT_E_TOOMANY_ENLISTMENTS)
                    {
                        throw TransactionException.Create(
                                  SR.OletxTooManyEnlistments,
                                  comException,
                                  enlistment == null ? Guid.Empty : enlistment.DistributedTxId);
                    }

                    OletxTransactionManager.ProxyException(comException);

                    throw;
                }
            }

            enlistmentSucceeded = true;
        }
        finally
        {
            if (!enlistmentSucceeded &&
                (enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != 0 &&
                undecidedEnlistmentsIncremented)
            {
                oletxTransaction.RealTransaction.DecrementUndecidedEnlistments();
            }
        }

        return(enlistment);
    }