internal DtcTransactionManager(string nodeName, OletxTransactionManager oletxTm)
 {
     this.nodeName         = nodeName;
     this.oletxTm          = oletxTm;
     this.initialized      = false;
     this.proxyShimFactory = OletxTransactionManager.proxyShimFactory;
 }
Ejemplo n.º 2
0
 internal DtcTransactionManager( string nodeName, OletxTransactionManager oletxTm )
 {
     this.nodeName = nodeName;
     this.oletxTm = oletxTm;
     this.initialized = false;
     this.proxyShimFactory = OletxTransactionManager.proxyShimFactory;
 }
 internal void Commit()
 {
     try
     {
         this.transactionShim.Commit();
     }
     catch (COMException exception)
     {
         if ((System.Transactions.Oletx.NativeMethods.XACT_E_ABORTED == exception.ErrorCode) || (System.Transactions.Oletx.NativeMethods.XACT_E_INDOUBT == exception.ErrorCode))
         {
             Interlocked.CompareExchange <Exception>(ref this.innerException, exception, null);
             if (DiagnosticTrace.Verbose)
             {
                 ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
             }
         }
         else
         {
             if (System.Transactions.Oletx.NativeMethods.XACT_E_ALREADYINPROGRESS == exception.ErrorCode)
             {
                 throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TransactionAlreadyOver"), exception);
             }
             OletxTransactionManager.ProxyException(exception);
             throw;
         }
     }
 }
Ejemplo n.º 4
0
 private void Initialize()
 {
     if (!this.initialized)
     {
         OletxInternalResourceManager internalResourceManager = this.oletxTm.internalResourceManager;
         IntPtr zero = IntPtr.Zero;
         IResourceManagerShim resourceManagerShim = null;
         bool            nodeNameMatches          = false;
         CoTaskMemHandle whereaboutsBuffer        = null;
         RuntimeHelpers.PrepareConstrainedRegions();
         try
         {
             zero = HandleTable.AllocHandle(internalResourceManager);
             this.proxyShimFactory.ConnectToProxy(this.nodeName, internalResourceManager.Identifier, zero, out nodeNameMatches, out this.whereaboutsSize, out whereaboutsBuffer, out resourceManagerShim);
             if (!nodeNameMatches)
             {
                 throw new NotSupportedException(System.Transactions.SR.GetString("ProxyCannotSupportMultipleNodeNames"));
             }
             if ((whereaboutsBuffer != null) && (this.whereaboutsSize != 0))
             {
                 this.whereabouts = new byte[this.whereaboutsSize];
                 Marshal.Copy(whereaboutsBuffer.DangerousGetHandle(), this.whereabouts, 0, Convert.ToInt32(this.whereaboutsSize));
             }
             internalResourceManager.resourceManagerShim = resourceManagerShim;
             internalResourceManager.CallReenlistComplete();
             this.initialized = true;
         }
         catch (COMException exception)
         {
             if (System.Transactions.Oletx.NativeMethods.XACT_E_NOTSUPPORTED == exception.ErrorCode)
             {
                 throw new NotSupportedException(System.Transactions.SR.GetString("CannotSupportNodeNameSpecification"));
             }
             OletxTransactionManager.ProxyException(exception);
             throw TransactionManagerCommunicationException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TransactionManagerCommunicationException"), exception);
         }
         finally
         {
             if (whereaboutsBuffer != null)
             {
                 whereaboutsBuffer.Close();
             }
             if (!this.initialized)
             {
                 if ((zero != IntPtr.Zero) && (resourceManagerShim == null))
                 {
                     HandleTable.FreeHandle(zero);
                 }
                 if (this.whereabouts != null)
                 {
                     this.whereabouts     = null;
                     this.whereaboutsSize = 0;
                 }
             }
         }
     }
 }
 internal void Rollback()
 {
     lock (this)
     {
         if ((TransactionStatus.Aborted != this.status) && (this.status != TransactionStatus.Active))
         {
             throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TransactionAlreadyOver"), null);
         }
         if (TransactionStatus.Aborted == this.status)
         {
             return;
         }
         if (0 < this.undecidedEnlistmentCount)
         {
             this.doomed = true;
         }
         else if (this.tooLateForEnlistments)
         {
             throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TransactionAlreadyOver"), null);
         }
         if (this.phase0EnlistVolatilementContainerList != null)
         {
             foreach (OletxPhase0VolatileEnlistmentContainer container in this.phase0EnlistVolatilementContainerList)
             {
                 container.RollbackFromTransaction();
             }
         }
         if (this.phase1EnlistVolatilementContainer != null)
         {
             this.phase1EnlistVolatilementContainer.RollbackFromTransaction();
         }
     }
     try
     {
         this.transactionShim.Abort();
     }
     catch (COMException exception)
     {
         if (System.Transactions.Oletx.NativeMethods.XACT_E_ALREADYINPROGRESS == exception.ErrorCode)
         {
             if (!this.doomed)
             {
                 throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TransactionAlreadyOver"), exception);
             }
             if (DiagnosticTrace.Verbose)
             {
                 ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
             }
         }
         else
         {
             OletxTransactionManager.ProxyException(exception);
             throw;
         }
     }
 }
Ejemplo n.º 6
0
 private static Oletx.OletxTransactionManager CheckTransactionManager(string nodeName)
 {
     Oletx.OletxTransactionManager tm = DistributedTransactionManager;
     if (!((tm.NodeName == null && (nodeName == null || nodeName.Length == 0)) ||
           (tm.NodeName != null && tm.NodeName.Equals(nodeName))))
     {
         throw new ArgumentException(SR.GetString(SR.InvalidRecoveryInformation), "recoveryInformation");
     }
     return(tm);
 }
 internal void TMDownFromInternalRM(OletxTransactionManager oletxTm)
 {
     lock (this)
     {
         if ((base.oletxTransaction == null) || (oletxTm == base.oletxTransaction.realOletxTransaction.OletxTransactionManagerInstance))
         {
             this.tmWentDown = true;
         }
     }
 }
Ejemplo n.º 8
0
 internal OletxResourceManager(OletxTransactionManager transactionManager, Guid resourceManagerIdentifier)
 {
     this.oletxTransactionManager   = transactionManager;
     this.resourceManagerIdentifier = resourceManagerIdentifier;
     this.enlistmentHashtable       = new Hashtable();
     this.reenlistList        = new ArrayList();
     this.reenlistPendingList = new ArrayList();
     this.reenlistThreadTimer = null;
     this.reenlistThread      = null;
     this.recoveryCompleteCalledByApplication = false;
 }
 internal OletxResourceManager(OletxTransactionManager transactionManager, Guid resourceManagerIdentifier)
 {
     this.oletxTransactionManager = transactionManager;
     this.resourceManagerIdentifier = resourceManagerIdentifier;
     this.enlistmentHashtable = new Hashtable();
     this.reenlistList = new ArrayList();
     this.reenlistPendingList = new ArrayList();
     this.reenlistThreadTimer = null;
     this.reenlistThread = null;
     this.recoveryCompleteCalledByApplication = false;
 }
Ejemplo n.º 10
0
        internal bool CallProxyReenlistComplete()
        {
            bool flag = false;

            if (this.RecoveryCompleteCalledByApplication)
            {
                IResourceManagerShim resourceManagerShim = null;
                try
                {
                    try
                    {
                        resourceManagerShim = this.ResourceManagerShim;
                        if (resourceManagerShim != null)
                        {
                            resourceManagerShim.ReenlistComplete();
                            flag = true;
                        }
                    }
                    catch (COMException exception)
                    {
                        if ((System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN == exception.ErrorCode) || (System.Transactions.Oletx.NativeMethods.XACT_E_TMNOTAVAILABLE == exception.ErrorCode))
                        {
                            flag = false;
                            if (DiagnosticTrace.Verbose)
                            {
                                ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
                            }
                            return(flag);
                        }
                        if (System.Transactions.Oletx.NativeMethods.XACT_E_RECOVERYALREADYDONE != exception.ErrorCode)
                        {
                            OletxTransactionManager.ProxyException(exception);
                            throw;
                        }
                        return(true);
                    }
                    return(flag);
                }
                finally
                {
                    resourceManagerShim = null;
                }
            }
            return(true);
        }
        internal RealOletxTransaction(OletxTransactionManager transactionManager, ITransactionShim transactionShim, OutcomeEnlistment outcomeEnlistment, Guid identifier, OletxTransactionIsolationLevel oletxIsoLevel, bool isRoot)
        {
            bool flag = false;

            try
            {
                this.oletxTransactionManager = transactionManager;
                this.transactionShim         = transactionShim;
                this.outcomeEnlistment       = outcomeEnlistment;
                this.txGuid         = identifier;
                this.isolationLevel = OletxTransactionManager.ConvertIsolationLevelFromProxyValue(oletxIsoLevel);
                this.status         = TransactionStatus.Active;
                this.undisposedOletxTransactionCount       = 0;
                this.phase0EnlistVolatilementContainerList = null;
                this.phase1EnlistVolatilementContainer     = null;
                this.tooLateForEnlistments = false;
                this.internalTransaction   = null;
                this.creationTime          = DateTime.UtcNow;
                this.lastStateChangeTime   = this.creationTime;
                this.internalClone         = new OletxTransaction(this);
                if (this.outcomeEnlistment != null)
                {
                    this.outcomeEnlistment.SetRealTransaction(this);
                }
                else
                {
                    this.status = TransactionStatus.InDoubt;
                }
                if (DiagnosticTrace.HaveListeners)
                {
                    DiagnosticTrace.TraceTransfer(this.txGuid);
                }
                flag = true;
            }
            finally
            {
                if (!flag && (this.outcomeEnlistment != null))
                {
                    this.outcomeEnlistment.UnregisterOutcomeCallback();
                    this.outcomeEnlistment = null;
                }
            }
        }
 internal RealOletxTransaction(OletxTransactionManager transactionManager, ITransactionShim transactionShim, OutcomeEnlistment outcomeEnlistment, Guid identifier, OletxTransactionIsolationLevel oletxIsoLevel, bool isRoot)
 {
     bool flag = false;
     try
     {
         this.oletxTransactionManager = transactionManager;
         this.transactionShim = transactionShim;
         this.outcomeEnlistment = outcomeEnlistment;
         this.txGuid = identifier;
         this.isolationLevel = OletxTransactionManager.ConvertIsolationLevelFromProxyValue(oletxIsoLevel);
         this.status = TransactionStatus.Active;
         this.undisposedOletxTransactionCount = 0;
         this.phase0EnlistVolatilementContainerList = null;
         this.phase1EnlistVolatilementContainer = null;
         this.tooLateForEnlistments = false;
         this.internalTransaction = null;
         this.creationTime = DateTime.UtcNow;
         this.lastStateChangeTime = this.creationTime;
         this.internalClone = new OletxTransaction(this);
         if (this.outcomeEnlistment != null)
         {
             this.outcomeEnlistment.SetRealTransaction(this);
         }
         else
         {
             this.status = TransactionStatus.InDoubt;
         }
         if (DiagnosticTrace.HaveListeners)
         {
             DiagnosticTrace.TraceTransfer(this.txGuid);
         }
         flag = true;
     }
     finally
     {
         if (!flag && (this.outcomeEnlistment != null))
         {
             this.outcomeEnlistment.UnregisterOutcomeCallback();
             this.outcomeEnlistment = null;
         }
     }
 }
Ejemplo n.º 13
0
        internal OletxResourceManager(
            OletxTransactionManager transactionManager,
            Guid resourceManagerIdentifier
            )
        {
            Debug.Assert( null != transactionManager, "Argument is null" );

            // This will get set later, after the resource manager is created with the proxy.
            this.resourceManagerShim = null;
            this.oletxTransactionManager = transactionManager;
            this.resourceManagerIdentifier = resourceManagerIdentifier;

            this.enlistmentHashtable = new Hashtable();
            this.reenlistList = new ArrayList();
            this.reenlistPendingList = new ArrayList();

            reenlistThreadTimer = null;
            reenlistThread = null;
            recoveryCompleteCalledByApplication = false;
        }
Ejemplo n.º 14
0
        internal void TMDownFromInternalRM(OletxTransactionManager oletxTM)
        {
            OletxEnlistment       enlistment = null;
            IDictionaryEnumerator enumerator = null;
            Hashtable             hashtable  = null;

            this.ResourceManagerShim = null;
            lock (this.enlistmentHashtable.SyncRoot)
            {
                hashtable = (Hashtable)this.enlistmentHashtable.Clone();
            }
            enumerator = hashtable.GetEnumerator();
            while (enumerator.MoveNext())
            {
                enlistment = enumerator.Value as OletxEnlistment;
                if (enlistment != null)
                {
                    enlistment.TMDownFromInternalRM(oletxTM);
                }
            }
        }
 internal OletxInternalResourceManager(OletxTransactionManager oletxTm)
 {
     this.oletxTm = oletxTm;
     this.myGuid = Guid.NewGuid();
 }
Ejemplo n.º 16
0
        internal void TMDownFromInternalRM( OletxTransactionManager oletxTm )
        {
            lock ( this )
            {
                // If we don't have an oletxTransaction or the passed oletxTm matches that of my oletxTransaction, the TM went down.
                if ( ( null == this.oletxTransaction ) || ( oletxTm == this.oletxTransaction.realOletxTransaction.OletxTransactionManagerInstance ) )
                {
                    this.tmWentDown = true;
                }
            }

            return;
        }
 internal void TMDownFromInternalRM(OletxTransactionManager oletxTM)
 {
     OletxEnlistment enlistment = null;
     IDictionaryEnumerator enumerator = null;
     Hashtable hashtable = null;
     this.ResourceManagerShim = null;
     lock (this.enlistmentHashtable.SyncRoot)
     {
         hashtable = (Hashtable) this.enlistmentHashtable.Clone();
     }
     enumerator = hashtable.GetEnumerator();
     while (enumerator.MoveNext())
     {
         enlistment = enumerator.Value as OletxEnlistment;
         if (enlistment != null)
         {
             enlistment.TMDownFromInternalRM(oletxTM);
         }
     }
 }
        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 void TMDownFromInternalRM(OletxTransactionManager oletxTm)
 {
     lock (this)
     {
         if ((base.oletxTransaction == null) || (oletxTm == base.oletxTransaction.realOletxTransaction.OletxTransactionManagerInstance))
         {
             this.tmWentDown = true;
         }
     }
 }
Ejemplo n.º 20
0
        // Common constructor used by all types of constructors
        // Create a clean and fresh transaction.
        internal RealOletxTransaction(OletxTransactionManager transactionManager, 
            ITransactionShim transactionShim,
            OutcomeEnlistment outcomeEnlistment,
            Guid identifier,
            OletxTransactionIsolationLevel oletxIsoLevel,
            bool isRoot )
        {
            bool successful = false;

            try
            {
                // initialize the member fields
                this.oletxTransactionManager = transactionManager;
                this.transactionShim = transactionShim;
                this.outcomeEnlistment = outcomeEnlistment;
                this.txGuid = identifier;
                this.isolationLevel = OletxTransactionManager.ConvertIsolationLevelFromProxyValue( oletxIsoLevel );
                this.status = TransactionStatus.Active;
                this.undisposedOletxTransactionCount = 0;
                this.phase0EnlistVolatilementContainerList = null;
                this.phase1EnlistVolatilementContainer = null;
                this.tooLateForEnlistments = false;
                this.internalTransaction = null;

                this.creationTime = DateTime.UtcNow;
                this.lastStateChangeTime = this.creationTime;

                // Connect this object with the OutcomeEnlistment.
                this.internalClone = new OletxTransaction( this );

                // We have have been created without an outcome enlistment if it was too late to create
                // a clone from the ITransactionNative that we were created from.
                if ( null != this.outcomeEnlistment )
                {
                    this.outcomeEnlistment.SetRealTransaction( this );
                }
                else
                {
                    this.status = TransactionStatus.InDoubt;
                }

                if ( DiagnosticTrace.HaveListeners )
                {
                    DiagnosticTrace.TraceTransfer(this.txGuid);
                }

                successful = true;
            }
            finally
            {
                if (!successful)
                {
                    if (this.outcomeEnlistment != null)
                    {
                        this.outcomeEnlistment.UnregisterOutcomeCallback();
                        this.outcomeEnlistment = null;
                    }
                }
            }
               
        }
        internal OletxVolatileEnlistmentContainer AddDependentClone(bool delayCommit)
        {
            IVoterBallotShim      voterBallotShim = null;
            IPhase0EnlistmentShim shim2           = null;
            bool flag2 = false;
            bool flag  = false;
            OletxVolatileEnlistmentContainer       container3 = null;
            OletxPhase0VolatileEnlistmentContainer container  = null;
            OletxPhase1VolatileEnlistmentContainer target     = null;
            bool   flag3 = false;
            bool   flag5 = false;
            IntPtr zero  = IntPtr.Zero;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                lock (this)
                {
                    if (delayCommit)
                    {
                        if (this.phase0EnlistVolatilementContainerList == null)
                        {
                            this.phase0EnlistVolatilementContainerList = new ArrayList(1);
                        }
                        if (this.phase0EnlistVolatilementContainerList.Count == 0)
                        {
                            container = new OletxPhase0VolatileEnlistmentContainer(this);
                            flag      = true;
                        }
                        else
                        {
                            container = this.phase0EnlistVolatilementContainerList[this.phase0EnlistVolatilementContainerList.Count - 1] as OletxPhase0VolatileEnlistmentContainer;
                            if (container != null)
                            {
                                this.TakeContainerLock(container, ref flag5);
                            }
                            if (!container.NewEnlistmentsAllowed)
                            {
                                this.ReleaseContainerLock(container, ref flag5);
                                container = new OletxPhase0VolatileEnlistmentContainer(this);
                                flag      = true;
                            }
                            else
                            {
                                flag = false;
                            }
                        }
                        if (flag)
                        {
                            zero = HandleTable.AllocHandle(container);
                        }
                    }
                    else if (this.phase1EnlistVolatilementContainer == null)
                    {
                        target             = new OletxPhase1VolatileEnlistmentContainer(this);
                        flag2              = true;
                        target.voterHandle = HandleTable.AllocHandle(target);
                    }
                    else
                    {
                        flag2  = false;
                        target = this.phase1EnlistVolatilementContainer;
                    }
                    try
                    {
                        if (container != null)
                        {
                            this.TakeContainerLock(container, ref flag5);
                        }
                        if (flag)
                        {
                            this.transactionShim.Phase0Enlist(zero, out shim2);
                            container.Phase0EnlistmentShim = shim2;
                        }
                        if (flag2)
                        {
                            this.OletxTransactionManagerInstance.dtcTransactionManagerLock.AcquireReaderLock(-1);
                            try
                            {
                                this.transactionShim.CreateVoter(target.voterHandle, out voterBallotShim);
                                flag3 = true;
                            }
                            finally
                            {
                                this.OletxTransactionManagerInstance.dtcTransactionManagerLock.ReleaseReaderLock();
                            }
                            target.VoterBallotShim = voterBallotShim;
                        }
                        if (delayCommit)
                        {
                            if (flag)
                            {
                                this.phase0EnlistVolatilementContainerList.Add(container);
                            }
                            container.AddDependentClone();
                            return(container);
                        }
                        if (flag2)
                        {
                            this.phase1EnlistVolatilementContainer = target;
                        }
                        target.AddDependentClone();
                        return(target);
                    }
                    catch (COMException exception)
                    {
                        OletxTransactionManager.ProxyException(exception);
                        throw;
                    }
                    return(container3);
                }
            }
            finally
            {
                if (container != null)
                {
                    this.ReleaseContainerLock(container, ref flag5);
                }
                if ((zero != IntPtr.Zero) && (container.Phase0EnlistmentShim == null))
                {
                    HandleTable.FreeHandle(zero);
                }
                if ((!flag3 && (target != null)) && ((target.voterHandle != IntPtr.Zero) && flag2))
                {
                    HandleTable.FreeHandle(target.voterHandle);
                }
            }
            return(container3);
        }
Ejemplo n.º 22
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);
        }
        void Initialize()
        {
            if (this.initialized)
            {
                return;
            }

            OletxInternalResourceManager internalRM = this.oletxTm.internalResourceManager;
            IntPtr handle = IntPtr.Zero;
            IResourceManagerShim resourceManagerShim = null;
            bool nodeNameMatches = false;

            CoTaskMemHandle whereaboutsBuffer = null;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                handle = HandleTable.AllocHandle(internalRM);

                this.proxyShimFactory.ConnectToProxy(
                    this.nodeName,
                    internalRM.Identifier,
                    handle,
                    out nodeNameMatches,
                    out this.whereaboutsSize,
                    out whereaboutsBuffer,
                    out resourceManagerShim
                    );

                // If the node name does not match, throw.
                if (!nodeNameMatches)
                {
                    throw new NotSupportedException(SR.GetString(SR.ProxyCannotSupportMultipleNodeNames));
                }

                // Make a managed copy of the whereabouts.
                if ((null != whereaboutsBuffer) && (0 != this.whereaboutsSize))
                {
                    this.whereabouts = new byte[this.whereaboutsSize];
                    Marshal.Copy(whereaboutsBuffer.DangerousGetHandle(), this.whereabouts, 0, Convert.ToInt32(this.whereaboutsSize));
                }

                // Give the IResourceManagerShim to the internalRM and tell it to call ReenlistComplete.
                internalRM.resourceManagerShim = resourceManagerShim;
                internalRM.CallReenlistComplete();


                this.initialized = true;
            }
            catch (COMException ex)
            {
                if (NativeMethods.XACT_E_NOTSUPPORTED == ex.ErrorCode)
                {
                    throw new NotSupportedException(SR.GetString(SR.CannotSupportNodeNameSpecification));
                }

                OletxTransactionManager.ProxyException(ex);

                // Unfortunately MSDTCPRX may return unknown error codes when attempting to connect to MSDTC
                // that error should be propagated back as a TransactionManagerCommunicationException.
                throw TransactionManagerCommunicationException.Create(
                          SR.GetString(SR.TraceSourceOletx),
                          SR.GetString(SR.TransactionManagerCommunicationException),
                          ex
                          );
            }
            finally
            {
                if (null != whereaboutsBuffer)
                {
                    whereaboutsBuffer.Close();
                }

                // If we weren't successful at initializing ourself, clear things out
                // for next time around.
                if (!this.initialized)
                {
                    if (handle != IntPtr.Zero && null == resourceManagerShim)
                    {
                        HandleTable.FreeHandle(handle);
                    }

                    if (null != this.whereabouts)
                    {
                        this.whereabouts     = null;
                        this.whereaboutsSize = 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);
        }
Ejemplo n.º 25
0
        internal OletxCommittableTransaction CreateTransaction(
            TransactionOptions properties
            )
        {
            OletxCommittableTransaction tx = null;
            RealOletxTransaction        realTransaction = null;
            ITransactionShim            transactionShim = null;
            Guid txIdentifier = Guid.Empty;
            OutcomeEnlistment outcomeEnlistment = null;

            // Demand the distributed transation permission to create one of
            // these.
            DistributedTransactionPermission txPerm =
                new DistributedTransactionPermission(PermissionState.Unrestricted);

            txPerm.Demand();

            TransactionManager.ValidateIsolationLevel(properties.IsolationLevel);

            // Never create a transaction with an IsolationLevel of Unspecified.
            if (IsolationLevel.Unspecified == properties.IsolationLevel)
            {
                properties.IsolationLevel = configuredTransactionOptions.IsolationLevel;
            }

            properties.Timeout = TransactionManager.ValidateTimeout(properties.Timeout);

            this.dtcTransactionManagerLock.AcquireReaderLock(-1);
            try
            {
                //
                OletxTransactionIsolationLevel oletxIsoLevel = OletxTransactionManager.ConvertIsolationLevel(properties.IsolationLevel);
                UInt32 oletxTimeout = DtcTransactionManager.AdjustTimeout(properties.Timeout);

                outcomeEnlistment = new OutcomeEnlistment();
                IntPtr outcomeEnlistmentHandle = IntPtr.Zero;
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                    outcomeEnlistmentHandle = HandleTable.AllocHandle(outcomeEnlistment);

                    dtcTransactionManager.ProxyShimFactory.BeginTransaction(
                        oletxTimeout,
                        oletxIsoLevel,
                        outcomeEnlistmentHandle,
                        out txIdentifier,
                        out transactionShim
                        );
                }
                catch (COMException ex)
                {
                    OletxTransactionManager.ProxyException(ex);
                    throw;
                }
                finally
                {
                    if (transactionShim == null && outcomeEnlistmentHandle != IntPtr.Zero)
                    {
                        HandleTable.FreeHandle(outcomeEnlistmentHandle);
                    }
                }

                realTransaction = new RealOletxTransaction(
                    this,
                    transactionShim,
                    outcomeEnlistment,
                    txIdentifier,
                    oletxIsoLevel,
                    true
                    );
                tx = new OletxCommittableTransaction(realTransaction);
                if (DiagnosticTrace.Information)
                {
                    TransactionCreatedTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx),
                                                        tx.TransactionTraceId
                                                        );
                }
            }
            finally
            {
                this.dtcTransactionManagerLock.ReleaseReaderLock();
            }

            return(tx);
        }
Ejemplo n.º 26
0
        // This is called by the internal RM when it gets a TM Down notification.  This routine will
        // tell the enlistments about the TMDown from the internal RM.  The enlistments will then
        // decide what to do, based on their state.  This is mainly to work around COMPlus bug 36760/36758,
        // where Phase0 enlistments get Phase0Request( abortHint = false ) when the TM goes down.  We want
        // to try to avoid telling the application to prepare when we know the transaction will abort.
        // We can't do this out of the normal TMDown notification to the RM because it is too late.  The
        // Phase0Request gets sent before the TMDown notification.
        internal void TMDownFromInternalRM( OletxTransactionManager oletxTM )
        {
            Hashtable localEnlistmentHashtable = null;
            IDictionaryEnumerator enlistEnum = null;
            OletxEnlistment enlistment = null;

            // If the internal RM got a TMDown, we will shortly, so null out our ResourceManagerShim now.
            this.ResourceManagerShim = null;

            // Make our own copy of the hashtable of enlistments.
            lock ( enlistmentHashtable.SyncRoot )
            {
                localEnlistmentHashtable = (Hashtable) this.enlistmentHashtable.Clone();
            }

            // Tell all of our enlistments that the TM went down.  The proxy only
            // tells enlistments that are in the Prepared state, but we want our Phase0
            // enlistments to know so they can avoid sending Prepare when they get a
            // Phase0Request - COMPlus bug 36760/36758.
            enlistEnum = localEnlistmentHashtable.GetEnumerator();
            while ( enlistEnum.MoveNext() )
            {
                enlistment = enlistEnum.Value as OletxEnlistment;
                if ( null != enlistment )
                {
                    enlistment.TMDownFromInternalRM( oletxTM );
                }
            }

        }
Ejemplo n.º 27
0
 internal OletxInternalResourceManager(OletxTransactionManager oletxTm)
 {
     this.oletxTm = oletxTm;
     this.myGuid  = Guid.NewGuid();
 }
Ejemplo n.º 28
0
        static public Enlistment Reenlist(
            Guid resourceManagerIdentifier,
            byte[] recoveryInformation,
            IEnlistmentNotification enlistmentNotification
            )
        {
            if (resourceManagerIdentifier == Guid.Empty)
            {
                throw new ArgumentException(SR.GetString(SR.BadResourceManagerId), "resourceManagerIdentifier");
            }

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

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

            if (!TransactionManager._platformValidated)
            {
                TransactionManager.ValidatePlatform();
            }

            if (DiagnosticTrace.Verbose)
            {
                MethodEnteredTraceRecord.Trace(SR.GetString(SR.TraceSourceBase),
                                               "TransactionManager.Reenlist"
                                               );
            }

            if (DiagnosticTrace.Information)
            {
                ReenlistTraceRecord.Trace(SR.GetString(SR.TraceSourceBase),
                                          resourceManagerIdentifier
                                          );
            }

            // Put the recovery information into a stream.
            MemoryStream stream = new MemoryStream(recoveryInformation);
            int          recoveryInformationVersion = 0;
            string       nodeName = null;

            byte[] resourceManagerRecoveryInformation = null;

            try
            {
                BinaryReader reader = new BinaryReader(stream);
                recoveryInformationVersion = reader.ReadInt32();

                if (recoveryInformationVersion == TransactionManager.recoveryInformationVersion1)
                {
                    nodeName = reader.ReadString();

                    resourceManagerRecoveryInformation = reader.ReadBytes(recoveryInformation.Length - checked ((int)stream.Position));
                }
                else
                {
                    if (DiagnosticTrace.Error)
                    {
                        TransactionExceptionTraceRecord.Trace(SR.GetString(SR.TraceSourceBase),
                                                              SR.GetString(SR.UnrecognizedRecoveryInformation)
                                                              );
                    }
                    throw new ArgumentException(SR.GetString(SR.UnrecognizedRecoveryInformation), "recoveryInformation");
                }
            }
            catch (System.IO.EndOfStreamException e)
            {
                if (DiagnosticTrace.Error)
                {
                    TransactionExceptionTraceRecord.Trace(SR.GetString(SR.TraceSourceBase),
                                                          SR.GetString(SR.UnrecognizedRecoveryInformation)
                                                          );
                }
                throw new ArgumentException(SR.GetString(SR.UnrecognizedRecoveryInformation), "recoveryInformation", e);
            }
            catch (System.FormatException e)
            {
                if (DiagnosticTrace.Error)
                {
                    TransactionExceptionTraceRecord.Trace(SR.GetString(SR.TraceSourceBase),
                                                          SR.GetString(SR.UnrecognizedRecoveryInformation)
                                                          );
                }
                throw new ArgumentException(SR.GetString(SR.UnrecognizedRecoveryInformation), "recoveryInformation", e);
            }
            finally
            {
                stream.Close();
            }

            Oletx.OletxTransactionManager transactionManager = CheckTransactionManager(nodeName);

            // Now ask the Transaction Manager to reenlist.
            object     syncRoot    = new object();
            Enlistment returnValue = new Enlistment(enlistmentNotification, syncRoot);

            EnlistmentState._EnlistmentStatePromoted.EnterState(returnValue.InternalEnlistment);

            returnValue.InternalEnlistment.PromotedEnlistment =
                transactionManager.ReenlistTransaction(
                    resourceManagerIdentifier,
                    resourceManagerRecoveryInformation,
                    (RecoveringInternalEnlistment)returnValue.InternalEnlistment
                    );

            if (DiagnosticTrace.Verbose)
            {
                MethodExitedTraceRecord.Trace(SR.GetString(SR.TraceSourceBase),
                                              "TransactionManager.Reenlist"
                                              );
            }

            return(returnValue);
        }