コード例 #1
0
        private void InvokeOutcomeFunction(TransactionStatus status)
        {
            WeakReference weakRealTransaction = null;

            lock (this)
            {
                if (this.haveIssuedOutcome)
                {
                    return;
                }
                this.haveIssuedOutcome = true;
                this.savedStatus       = status;
                weakRealTransaction    = this.weakRealTransaction;
            }
            if (weakRealTransaction != null)
            {
                RealOletxTransaction target = weakRealTransaction.Target as RealOletxTransaction;
                if (target != null)
                {
                    target.FireOutcome(status);
                    if (target.phase0EnlistVolatilementContainerList != null)
                    {
                        foreach (OletxPhase0VolatileEnlistmentContainer container in target.phase0EnlistVolatilementContainerList)
                        {
                            container.OutcomeFromTransaction(status);
                        }
                    }
                    if (((TransactionStatus.Aborted == status) || (TransactionStatus.InDoubt == status)) && (target.phase1EnlistVolatilementContainer != null))
                    {
                        target.phase1EnlistVolatilementContainer.OutcomeFromTransaction(status);
                    }
                }
                weakRealTransaction.Target = null;
            }
        }
コード例 #2
0
        internal void TMDown()
        {
            bool flag = true;
            RealOletxTransaction realTx = null;

            lock (this)
            {
                if (this.weakRealTransaction != null)
                {
                    realTx = this.weakRealTransaction.Target as RealOletxTransaction;
                }
            }
            if (realTx != null)
            {
                lock (realTx)
                {
                    flag = this.TransactionIsInDoubt(realTx);
                }
            }
            if (flag)
            {
                this.InDoubt();
            }
            else
            {
                this.Aborted();
            }
        }
コード例 #3
0
 internal bool TransactionIsInDoubt(RealOletxTransaction realTx)
 {
     if ((realTx.committableTransaction != null) && !realTx.committableTransaction.CommitCalled)
     {
         return(false);
     }
     return(realTx.UndecidedEnlistments == 0);
 }
 internal OletxPhase1VolatileEnlistmentContainer(RealOletxTransaction realOletxTransaction)
 {
     base.realOletxTransaction = realOletxTransaction;
     base.phase = -1;
     base.outstandingNotifications = 0;
     base.incompleteDependentClones = 0;
     base.alreadyVoted = false;
     base.collectedVoteYes = true;
     base.enlistmentList = new ArrayList();
     realOletxTransaction.IncrementUndecidedEnlistments();
 }
コード例 #5
0
 internal OletxPhase1VolatileEnlistmentContainer(RealOletxTransaction realOletxTransaction)
 {
     base.realOletxTransaction = realOletxTransaction;
     base.phase = -1;
     base.outstandingNotifications  = 0;
     base.incompleteDependentClones = 0;
     base.alreadyVoted     = false;
     base.collectedVoteYes = true;
     base.enlistmentList   = new ArrayList();
     realOletxTransaction.IncrementUndecidedEnlistments();
 }
コード例 #6
0
        internal OletxCommittableTransaction CreateTransaction(TransactionOptions properties)
        {
            OletxCommittableTransaction transaction          = null;
            ITransactionShim            transactionShim      = null;
            RealOletxTransaction        realOletxTransaction = null;
            Guid empty = Guid.Empty;
            OutcomeEnlistment target = null;

            new DistributedTransactionPermission(PermissionState.Unrestricted).Demand();
            TransactionManager.ValidateIsolationLevel(properties.IsolationLevel);
            if (IsolationLevel.Unspecified == properties.IsolationLevel)
            {
                properties.IsolationLevel = this.configuredTransactionOptions.IsolationLevel;
            }
            properties.Timeout = TransactionManager.ValidateTimeout(properties.Timeout);
            this.dtcTransactionManagerLock.AcquireReaderLock(-1);
            try
            {
                OletxTransactionIsolationLevel isolationLevel = ConvertIsolationLevel(properties.IsolationLevel);
                uint timeout = System.Transactions.Oletx.DtcTransactionManager.AdjustTimeout(properties.Timeout);
                target = new OutcomeEnlistment();
                IntPtr zero = IntPtr.Zero;
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                    zero = HandleTable.AllocHandle(target);
                    this.dtcTransactionManager.ProxyShimFactory.BeginTransaction(timeout, isolationLevel, zero, out empty, out transactionShim);
                }
                catch (COMException exception)
                {
                    ProxyException(exception);
                    throw;
                }
                finally
                {
                    if ((transactionShim == null) && (zero != IntPtr.Zero))
                    {
                        HandleTable.FreeHandle(zero);
                    }
                }
                realOletxTransaction = new RealOletxTransaction(this, transactionShim, target, empty, isolationLevel, true);
                transaction          = new OletxCommittableTransaction(realOletxTransaction);
                if (DiagnosticTrace.Information)
                {
                    TransactionCreatedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), transaction.TransactionTraceId);
                }
            }
            finally
            {
                this.dtcTransactionManagerLock.ReleaseReaderLock();
            }
            return(transaction);
        }
 internal OletxDependentTransaction(RealOletxTransaction realTransaction, bool delayCommit) : base(realTransaction)
 {
     if (realTransaction == null)
     {
         throw new ArgumentNullException("realTransaction");
     }
     this.volatileEnlistmentContainer = base.realOletxTransaction.AddDependentClone(delayCommit);
     if (DiagnosticTrace.Information)
     {
         DependentCloneCreatedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.TransactionTraceId, delayCommit ? DependentCloneOption.BlockCommitUntilComplete : DependentCloneOption.RollbackIfNotComplete);
     }
 }
コード例 #8
0
 internal OletxDependentTransaction(RealOletxTransaction realTransaction, bool delayCommit) : base(realTransaction)
 {
     if (realTransaction == null)
     {
         throw new ArgumentNullException("realTransaction");
     }
     this.volatileEnlistmentContainer = base.realOletxTransaction.AddDependentClone(delayCommit);
     if (DiagnosticTrace.Information)
     {
         DependentCloneCreatedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.TransactionTraceId, delayCommit ? DependentCloneOption.BlockCommitUntilComplete : DependentCloneOption.RollbackIfNotComplete);
     }
 }
 internal void SetRealTransaction(RealOletxTransaction realTx)
 {
     bool haveIssuedOutcome = false;
     TransactionStatus inDoubt = TransactionStatus.InDoubt;
     lock (this)
     {
         haveIssuedOutcome = this.haveIssuedOutcome;
         inDoubt = this.savedStatus;
         if (!haveIssuedOutcome)
         {
             this.weakRealTransaction = new WeakReference(realTx);
             this.txGuid = realTx.TxGuid;
         }
     }
     if (haveIssuedOutcome)
     {
         realTx.FireOutcome(inDoubt);
         if (((TransactionStatus.Aborted == inDoubt) || (TransactionStatus.InDoubt == inDoubt)) && (realTx.phase1EnlistVolatilementContainer != null))
         {
             realTx.phase1EnlistVolatilementContainer.OutcomeFromTransaction(inDoubt);
         }
     }
 }
コード例 #10
0
        internal OletxPhase0VolatileEnlistmentContainer(
            RealOletxTransaction realOletxTransaction
            )
        {
            Debug.Assert( null != realOletxTransaction, "Argument is null" );

            // This will be set later, after the caller creates the enlistment with the proxy.
            this.phase0EnlistmentShim = null;

            this.realOletxTransaction = realOletxTransaction;
            this.phase = -1;
            this.aborting = false;
            this.tmWentDown = false;
            this.outstandingNotifications = 0;
            this.incompleteDependentClones = 0;
            this.alreadyVoted = false;
            // If anybody votes false, this will get set to false.
            this.collectedVoteYes = true;
            this.enlistmentList = new ArrayList();

            // This is a new undecided enlistment on the transaction.  Do this last since it has side affects.
            realOletxTransaction.IncrementUndecidedEnlistments();
        }
コード例 #11
0
        internal void SetRealTransaction(RealOletxTransaction realTx)
        {
            bool haveIssuedOutcome    = false;
            TransactionStatus inDoubt = TransactionStatus.InDoubt;

            lock (this)
            {
                haveIssuedOutcome = this.haveIssuedOutcome;
                inDoubt           = this.savedStatus;
                if (!haveIssuedOutcome)
                {
                    this.weakRealTransaction = new WeakReference(realTx);
                    this.txGuid = realTx.TxGuid;
                }
            }
            if (haveIssuedOutcome)
            {
                realTx.FireOutcome(inDoubt);
                if (((TransactionStatus.Aborted == inDoubt) || (TransactionStatus.InDoubt == inDoubt)) && (realTx.phase1EnlistVolatilementContainer != null))
                {
                    realTx.phase1EnlistVolatilementContainer.OutcomeFromTransaction(inDoubt);
                }
            }
        }
コード例 #12
0
        public static Transaction GetTransactionFromExportCookie(
            byte[] cookie
            )
        {
            if ( !TransactionManager._platformValidated ) TransactionManager.ValidatePlatform();

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

            if ( cookie.Length < 32 )
            {
                throw new ArgumentException( SR.GetString( SR.InvalidArgument ), "cookie" );
            }

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

            byte[] cookieCopy = new byte[cookie.Length];
            Array.Copy(cookie, cookieCopy, cookie.Length);
            cookie = cookieCopy;

            Transaction transaction = null;
            ITransactionShim transactionShim = null;
            Guid txIdentifier = Guid.Empty;
            OletxTransactionIsolationLevel oletxIsoLevel = OletxTransactionIsolationLevel.ISOLATIONLEVEL_SERIALIZABLE;
            OutcomeEnlistment outcomeEnlistment = null;
            OletxTransaction oleTx = null;

            // Extract the transaction guid from the propagation token to see if we already have a
            // transaction object for the transaction.
            byte[] guidByteArray = new byte[16];
            for (int i = 0; i < guidByteArray.Length; i++ )
            {
                // In a cookie, the transaction guid is preceeded by a signature guid.
                guidByteArray[i] = cookie[i + 16];
            }

            Guid txId = new Guid( guidByteArray );

            // First check to see if there is a promoted LTM transaction with the same ID.  If there
            // is, just return that.
            transaction = TransactionManager.FindPromotedTransaction( txId );
            if ( null != transaction )
            {
                if ( DiagnosticTrace.Verbose )
                {
                    MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                        "TransactionInterop.GetTransactionFromExportCookie"
                        );
                }
                return transaction;
            }

            // We need to create a new transaction
            RealOletxTransaction realTx = null;
            OletxTransactionManager oletxTm = TransactionManager.DistributedTransactionManager;

            oletxTm.dtcTransactionManagerLock.AcquireReaderLock( -1 );
            try
            {
                outcomeEnlistment = new OutcomeEnlistment();
                IntPtr outcomeEnlistmentHandle = IntPtr.Zero;
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                    outcomeEnlistmentHandle = HandleTable.AllocHandle( outcomeEnlistment );
                    oletxTm.DtcTransactionManager.ProxyShimFactory.Import(
                        Convert.ToUInt32(cookie.Length),
                        cookie,
                        outcomeEnlistmentHandle,
                        out txIdentifier,
                        out oletxIsoLevel,
                        out transactionShim );
                }
                finally
                {
                    if ( transactionShim == null && outcomeEnlistmentHandle != IntPtr.Zero )
                    {
                        HandleTable.FreeHandle( outcomeEnlistmentHandle );
                    }
                }
            }
            catch ( COMException comException )
            {
                OletxTransactionManager.ProxyException( comException );

                // We are unsure of what the exception may mean.  It is possible that 
                // we could get E_FAIL when trying to contact a transaction manager that is
                // being blocked by a fire wall.  On the other hand we may get a COMException
                // based on bad data.  The more common situation is that the data is fine
                // (since it is generated by Microsoft code) and the problem is with 
                // communication.  So in this case we default for unknown exceptions to
                // assume that the problem is with communication.
                throw TransactionManagerCommunicationException.Create( SR.GetString( SR.TraceSourceOletx ), comException );
            }
            finally
            {
                oletxTm.dtcTransactionManagerLock.ReleaseReaderLock();
            }

            // We need to create a new RealOletxTransaction.
            realTx = new RealOletxTransaction(
                oletxTm,
                transactionShim,
                outcomeEnlistment,
                txIdentifier,
                oletxIsoLevel,
                false );

            // Now create the associated OletxTransaction.
            oleTx = new OletxTransaction( realTx );

            // If a transaction is found then FindOrCreate will Dispose the oletx
            // created.
            transaction = TransactionManager.FindOrCreatePromotedTransaction( txId, oleTx );

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

            return transaction;
        }
 internal bool TransactionIsInDoubt(RealOletxTransaction realTx)
 {
     if ((realTx.committableTransaction != null) && !realTx.committableTransaction.CommitCalled)
     {
         return false;
     }
     return (realTx.UndecidedEnlistments == 0);
 }
 public static Transaction GetTransactionFromDtcTransaction(IDtcTransaction transactionNative)
 {
     OletxXactTransInfo info;
     if (!TransactionManager._platformValidated)
     {
         TransactionManager.ValidatePlatform();
     }
     bool flag = false;
     ITransactionShim transactionShim = null;
     Guid empty = Guid.Empty;
     OletxTransactionIsolationLevel isolationLevel = OletxTransactionIsolationLevel.ISOLATIONLEVEL_SERIALIZABLE;
     OutcomeEnlistment target = null;
     RealOletxTransaction realOletxTransaction = null;
     OletxTransaction oletx = null;
     if (transactionNative == null)
     {
         throw new ArgumentNullException("transactionNative");
     }
     Transaction transaction = null;
     if (DiagnosticTrace.Verbose)
     {
         MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "TransactionInterop.GetTransactionFromDtc");
     }
     ITransactionNativeInternal internal2 = transactionNative as ITransactionNativeInternal;
     if (internal2 == null)
     {
         throw new ArgumentException(System.Transactions.SR.GetString("InvalidArgument"), "transactionNative");
     }
     try
     {
         internal2.GetTransactionInfo(out info);
     }
     catch (COMException exception2)
     {
         if (System.Transactions.Oletx.NativeMethods.XACT_E_NOTRANSACTION != exception2.ErrorCode)
         {
             throw;
         }
         flag = true;
         info.uow = Guid.Empty;
     }
     OletxTransactionManager distributedTransactionManager = TransactionManager.DistributedTransactionManager;
     if (!flag)
     {
         transaction = TransactionManager.FindPromotedTransaction(info.uow);
         if (null != transaction)
         {
             if (DiagnosticTrace.Verbose)
             {
                 MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "TransactionInterop.GetTransactionFromDtcTransaction");
             }
             return transaction;
         }
         distributedTransactionManager.dtcTransactionManagerLock.AcquireReaderLock(-1);
         try
         {
             target = new OutcomeEnlistment();
             IntPtr zero = IntPtr.Zero;
             RuntimeHelpers.PrepareConstrainedRegions();
             try
             {
                 zero = HandleTable.AllocHandle(target);
                 distributedTransactionManager.DtcTransactionManager.ProxyShimFactory.CreateTransactionShim(transactionNative, zero, out empty, out isolationLevel, out transactionShim);
             }
             finally
             {
                 if ((transactionShim == null) && (zero != IntPtr.Zero))
                 {
                     HandleTable.FreeHandle(zero);
                 }
             }
         }
         catch (COMException exception)
         {
             OletxTransactionManager.ProxyException(exception);
             throw;
         }
         finally
         {
             distributedTransactionManager.dtcTransactionManagerLock.ReleaseReaderLock();
         }
         realOletxTransaction = new RealOletxTransaction(distributedTransactionManager, transactionShim, target, empty, isolationLevel, false);
         oletx = new OletxTransaction(realOletxTransaction);
         transaction = TransactionManager.FindOrCreatePromotedTransaction(info.uow, oletx);
     }
     else
     {
         realOletxTransaction = new RealOletxTransaction(distributedTransactionManager, null, null, empty, OletxTransactionIsolationLevel.ISOLATIONLEVEL_SERIALIZABLE, false);
         oletx = new OletxTransaction(realOletxTransaction);
         transaction = new Transaction(oletx);
         TransactionManager.FireDistributedTransactionStarted(transaction);
         oletx.savedLtmPromotedTransaction = transaction;
         InternalTransaction.DistributedTransactionOutcome(transaction.internalTransaction, TransactionStatus.InDoubt);
     }
     if (DiagnosticTrace.Verbose)
     {
         MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "TransactionInterop.GetTransactionFromDtc");
     }
     return transaction;
 }
 public static Transaction GetTransactionFromExportCookie(byte[] cookie)
 {
     if (!TransactionManager._platformValidated)
     {
         TransactionManager.ValidatePlatform();
     }
     if (cookie == null)
     {
         throw new ArgumentNullException("cookie");
     }
     if (cookie.Length < 0x20)
     {
         throw new ArgumentException(System.Transactions.SR.GetString("InvalidArgument"), "cookie");
     }
     if (DiagnosticTrace.Verbose)
     {
         MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "TransactionInterop.GetTransactionFromExportCookie");
     }
     byte[] destinationArray = new byte[cookie.Length];
     Array.Copy(cookie, destinationArray, cookie.Length);
     cookie = destinationArray;
     Transaction transaction = null;
     ITransactionShim transactionShim = null;
     Guid empty = Guid.Empty;
     OletxTransactionIsolationLevel isolationLevel = OletxTransactionIsolationLevel.ISOLATIONLEVEL_SERIALIZABLE;
     OutcomeEnlistment target = null;
     OletxTransaction oletx = null;
     byte[] b = new byte[0x10];
     for (int i = 0; i < b.Length; i++)
     {
         b[i] = cookie[i + 0x10];
     }
     Guid transactionIdentifier = new Guid(b);
     transaction = TransactionManager.FindPromotedTransaction(transactionIdentifier);
     if (null != transaction)
     {
         if (DiagnosticTrace.Verbose)
         {
             MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "TransactionInterop.GetTransactionFromExportCookie");
         }
         return transaction;
     }
     RealOletxTransaction realOletxTransaction = null;
     OletxTransactionManager distributedTransactionManager = TransactionManager.DistributedTransactionManager;
     distributedTransactionManager.dtcTransactionManagerLock.AcquireReaderLock(-1);
     try
     {
         target = new OutcomeEnlistment();
         IntPtr zero = IntPtr.Zero;
         RuntimeHelpers.PrepareConstrainedRegions();
         try
         {
             zero = HandleTable.AllocHandle(target);
             distributedTransactionManager.DtcTransactionManager.ProxyShimFactory.Import(Convert.ToUInt32(cookie.Length), cookie, zero, out empty, out isolationLevel, out transactionShim);
         }
         finally
         {
             if ((transactionShim == null) && (zero != IntPtr.Zero))
             {
                 HandleTable.FreeHandle(zero);
             }
         }
     }
     catch (COMException exception)
     {
         OletxTransactionManager.ProxyException(exception);
         throw TransactionManagerCommunicationException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), exception);
     }
     finally
     {
         distributedTransactionManager.dtcTransactionManagerLock.ReleaseReaderLock();
     }
     realOletxTransaction = new RealOletxTransaction(distributedTransactionManager, transactionShim, target, empty, isolationLevel, false);
     oletx = new OletxTransaction(realOletxTransaction);
     transaction = TransactionManager.FindOrCreatePromotedTransaction(transactionIdentifier, oletx);
     if (DiagnosticTrace.Verbose)
     {
         MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "TransactionInterop.GetTransactionFromExportCookie");
     }
     return transaction;
 }
コード例 #16
0
ファイル: OleTxTransaction.cs プロジェクト: mind0n/hive
        internal void SetRealTransaction( RealOletxTransaction realTx )
        {
            bool localHaveIssuedOutcome = false;
            TransactionStatus localStatus = TransactionStatus.InDoubt;

            lock ( this )
            {
                localHaveIssuedOutcome = this.haveIssuedOutcome;
                localStatus = this.savedStatus;
                
                // We want to do this while holding the lock.
                if ( ! localHaveIssuedOutcome )
                {
                    // We don't use MemoryBarrier here because all access to these member variables is done while holding
                    // a lock on the object.

                    // We are going to use a weak reference so the transaction object can get garbage
                    // collected before we receive the outcome.
                    this.weakRealTransaction = new WeakReference(realTx);
            
                    // Save the transaction guid so that the transaction can be removed from the
                    // TransactionTable
                    this.txGuid = realTx.TxGuid;
                }
            }

            // We want to do this outside the lock because we are potentially calling out to user code.
            if ( localHaveIssuedOutcome )
            {
                realTx.FireOutcome( localStatus );

                // We may be getting this notification while there are still volatile prepare notifications outstanding.  Tell the
                // container to drive the aborted notification in that case.
                if ( ( ( TransactionStatus.Aborted == localStatus ) || ( TransactionStatus.InDoubt == localStatus ) ) &&
                   ( null != realTx.phase1EnlistVolatilementContainer ) )
                {
                    realTx.phase1EnlistVolatilementContainer.OutcomeFromTransaction( localStatus );
                }
            }
        }
コード例 #17
0
ファイル: OleTxTransaction.cs プロジェクト: mind0n/hive
        //
        // We need to figure out if the transaction is InDoubt as a result of TMDown.  This
        // can happen for a number of reasons.  For instance we have responded prepared
        // to all of our enlistments or we have no enlistments.
        //
        internal bool TransactionIsInDoubt(RealOletxTransaction realTx)
        {
            if ( null != realTx.committableTransaction && 
                 !realTx.committableTransaction.CommitCalled )
            {
                // If this is a committable transaction and commit has not been called
                // then we know the outcome.
                return false;
            }

            return realTx.UndecidedEnlistments == 0;
        }
コード例 #18
0
 /// <summary>
 /// Constructor for the Transaction object.  Specifies the TransactionManager instance that is
 /// creating the transaction.
 /// </summary>
 /// <param name="transactionManager">
 /// Specifies the TransactionManager instance that is creating the transaction.
 /// </param>
 internal OletxCommittableTransaction( RealOletxTransaction realOletxTransaction )
     : base( realOletxTransaction )
 {
     realOletxTransaction.committableTransaction = this;
 }
コード例 #19
0
ファイル: OleTxTransaction.cs プロジェクト: mind0n/hive
        internal OletxTransaction(RealOletxTransaction realOletxTransaction)
        {
            this.realOletxTransaction = realOletxTransaction;

            // Tell the realOletxTransaction that we are here.
            this.realOletxTransaction.OletxTransactionCreated();
        }
コード例 #20
0
 internal OletxTransaction(RealOletxTransaction realOletxTransaction)
 {
     this.traceIdentifier      = TransactionTraceIdentifier.Empty;
     this.realOletxTransaction = realOletxTransaction;
     this.realOletxTransaction.OletxTransactionCreated();
 }
コード例 #21
0
 /// <summary>
 /// Constructor for the Transaction object.  Specifies the TransactionManager instance that is
 /// creating the transaction.
 /// </summary>
 /// <param name="transactionManager">
 /// Specifies the TransactionManager instance that is creating the transaction.
 /// </param>
 internal OletxCommittableTransaction(RealOletxTransaction realOletxTransaction)
     : base(realOletxTransaction)
 {
     realOletxTransaction.committableTransaction = this;
 }
コード例 #22
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;

        }
コード例 #23
0
        public void TMDown()
        {
            // Let's set ourselves up for reinitialization with the proxy by releasing our
            // reference to the resource manager shim, which will release its reference
            // to the proxy when it destructs.
            this.resourceManagerShim = null;

            // We need to look through all the transactions and tell them about
            // the TMDown so they can tell their Phase0VolatileEnlistmentContainers.
            Transaction           tx        = null;
            RealOletxTransaction  realTx    = null;
            IDictionaryEnumerator tableEnum = null;

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

            // make a local copy of the hash table to avoid possible deadlocks when we lock both the global hash table
            // and the transaction object.
            Hashtable txHashTable = null;

            lock (TransactionManager.PromotedTransactionTable.SyncRoot)
            {
                txHashTable = (Hashtable)TransactionManager.PromotedTransactionTable.Clone();
            }

            // No need to lock my hashtable, nobody is going to change it.
            tableEnum = txHashTable.GetEnumerator();
            while (tableEnum.MoveNext())
            {
                WeakReference txWeakRef = (WeakReference)tableEnum.Value;
                if (null != txWeakRef)
                {
                    tx = (Transaction)txWeakRef.Target;
                    if (null != tx)
                    {
                        realTx = tx.internalTransaction.PromotedTransaction.realOletxTransaction;
                        // Only deal with transactions owned by my OletxTm.
                        if (realTx.OletxTransactionManagerInstance == this.oletxTm)
                        {
                            realTx.TMDown();
                        }
                    }
                }
            }

            // Now make a local copy of the hash table of resource managers and tell each of them.  This is to
            // deal with Durable EDPR=true (phase0) enlistments.  Each RM will also get a TMDown, but it will
            // come AFTER the "buggy" Phase0Request with abortHint=true - COMPlus
            Hashtable rmHashTable = null;

            if (null != OletxTransactionManager.resourceManagerHashTable)
            {
                OletxTransactionManager.resourceManagerHashTableLock.AcquireReaderLock(Timeout.Infinite);
                try
                {
                    rmHashTable = (Hashtable)OletxTransactionManager.resourceManagerHashTable.Clone();
                }
                finally
                {
                    OletxTransactionManager.resourceManagerHashTableLock.ReleaseReaderLock();
                }
            }

            if (null != rmHashTable)
            {
                // No need to lock my hashtable, nobody is going to change it.
                tableEnum = rmHashTable.GetEnumerator();
                while (tableEnum.MoveNext())
                {
                    OletxResourceManager oletxRM = (OletxResourceManager)tableEnum.Value;
                    if (null != oletxRM)
                    {
                        // When the RM spins through its enlistments, it will need to make sure that
                        // the enlistment is for this particular TM.
                        oletxRM.TMDownFromInternalRM(this.oletxTm);
                    }
                }
            }

            // Now let's reinitialize the shim.
            this.oletxTm.dtcTransactionManagerLock.AcquireWriterLock(-1);
            try
            {
                this.oletxTm.ReinitializeProxy();
            }
            finally
            {
                this.oletxTm.dtcTransactionManagerLock.ReleaseWriterLock();
            }

            if (DiagnosticTrace.Verbose)
            {
                MethodExitedTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx),
                                              "OletxInternalResourceManager.TMDown"
                                              );
            }
        }
コード例 #24
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);
        }
 internal OletxCommittableTransaction CreateTransaction(TransactionOptions properties)
 {
     OletxCommittableTransaction transaction = null;
     ITransactionShim transactionShim = null;
     RealOletxTransaction realOletxTransaction = null;
     Guid empty = Guid.Empty;
     OutcomeEnlistment target = null;
     new DistributedTransactionPermission(PermissionState.Unrestricted).Demand();
     TransactionManager.ValidateIsolationLevel(properties.IsolationLevel);
     if (IsolationLevel.Unspecified == properties.IsolationLevel)
     {
         properties.IsolationLevel = this.configuredTransactionOptions.IsolationLevel;
     }
     properties.Timeout = TransactionManager.ValidateTimeout(properties.Timeout);
     this.dtcTransactionManagerLock.AcquireReaderLock(-1);
     try
     {
         OletxTransactionIsolationLevel isolationLevel = ConvertIsolationLevel(properties.IsolationLevel);
         uint timeout = System.Transactions.Oletx.DtcTransactionManager.AdjustTimeout(properties.Timeout);
         target = new OutcomeEnlistment();
         IntPtr zero = IntPtr.Zero;
         RuntimeHelpers.PrepareConstrainedRegions();
         try
         {
             zero = HandleTable.AllocHandle(target);
             this.dtcTransactionManager.ProxyShimFactory.BeginTransaction(timeout, isolationLevel, zero, out empty, out transactionShim);
         }
         catch (COMException exception)
         {
             ProxyException(exception);
             throw;
         }
         finally
         {
             if ((transactionShim == null) && (zero != IntPtr.Zero))
             {
                 HandleTable.FreeHandle(zero);
             }
         }
         realOletxTransaction = new RealOletxTransaction(this, transactionShim, target, empty, isolationLevel, true);
         transaction = new OletxCommittableTransaction(realOletxTransaction);
         if (DiagnosticTrace.Information)
         {
             TransactionCreatedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), transaction.TransactionTraceId);
         }
     }
     finally
     {
         this.dtcTransactionManagerLock.ReleaseReaderLock();
     }
     return transaction;
 }
コード例 #26
0
        internal static OletxTransaction GetOletxTransactionFromTransmitterPropigationToken(
            byte[] propagationToken
            )
        {
            Guid identifier;
            OletxTransactionIsolationLevel oletxIsoLevel;
            OutcomeEnlistment outcomeEnlistment;
            ITransactionShim transactionShim = null;

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

            if ( propagationToken.Length < 24 )
            {
                throw new ArgumentException( SR.GetString( SR.InvalidArgument ), "propagationToken" );
            }

            byte[] propagationTokenCopy = new byte[propagationToken.Length];
            Array.Copy(propagationToken, propagationTokenCopy, propagationToken.Length);
            propagationToken = propagationTokenCopy;

            // First we need to create an OletxTransactionManager from Config.
            OletxTransactionManager oletxTm = TransactionManager.DistributedTransactionManager;

            oletxTm.dtcTransactionManagerLock.AcquireReaderLock( -1 );
            try
            {
                outcomeEnlistment = new OutcomeEnlistment();
                IntPtr outcomeEnlistmentHandle = IntPtr.Zero;
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                    outcomeEnlistmentHandle = HandleTable.AllocHandle( outcomeEnlistment );
                    oletxTm.DtcTransactionManager.ProxyShimFactory.ReceiveTransaction(
                        Convert.ToUInt32(propagationToken.Length),
                        propagationToken,
                        outcomeEnlistmentHandle,
                        out identifier,
                        out oletxIsoLevel,
                        out transactionShim
                        );
                }
                finally
                {
                    if ( transactionShim == null && outcomeEnlistmentHandle != IntPtr.Zero )
                    {
                        HandleTable.FreeHandle( outcomeEnlistmentHandle );
                    }
                }
            }
            catch ( COMException comException )
            {
                OletxTransactionManager.ProxyException( comException );

                // We are unsure of what the exception may mean.  It is possible that 
                // we could get E_FAIL when trying to contact a transaction manager that is
                // being blocked by a fire wall.  On the other hand we may get a COMException
                // based on bad data.  The more common situation is that the data is fine
                // (since it is generated by Microsoft code) and the problem is with 
                // communication.  So in this case we default for unknown exceptions to
                // assume that the problem is with communication.
                throw TransactionManagerCommunicationException.Create( SR.GetString( SR.TraceSourceOletx ), comException );
            }
            finally
            {
                oletxTm.dtcTransactionManagerLock.ReleaseReaderLock();
            }

            RealOletxTransaction realTx = null;

            realTx = new RealOletxTransaction(
                oletxTm,
                transactionShim,
                outcomeEnlistment,
                identifier,
                oletxIsoLevel,
                false );
            
            return new OletxTransaction( realTx );
        }
コード例 #27
0
        public void TMDown()
        {
            this.resourceManagerShim = null;
            Transaction           target = null;
            RealOletxTransaction  realOletxTransaction = null;
            IDictionaryEnumerator enumerator           = null;

            if (DiagnosticTrace.Verbose)
            {
                MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxInternalResourceManager.TMDown");
            }
            Hashtable hashtable2 = null;

            lock (TransactionManager.PromotedTransactionTable.SyncRoot)
            {
                hashtable2 = (Hashtable)TransactionManager.PromotedTransactionTable.Clone();
            }
            enumerator = hashtable2.GetEnumerator();
            while (enumerator.MoveNext())
            {
                WeakReference reference = (WeakReference)enumerator.Value;
                if (reference != null)
                {
                    target = (Transaction)reference.Target;
                    if (null != target)
                    {
                        realOletxTransaction = target.internalTransaction.PromotedTransaction.realOletxTransaction;
                        if (realOletxTransaction.OletxTransactionManagerInstance == this.oletxTm)
                        {
                            realOletxTransaction.TMDown();
                        }
                    }
                }
            }
            Hashtable hashtable = null;

            if (OletxTransactionManager.resourceManagerHashTable != null)
            {
                OletxTransactionManager.resourceManagerHashTableLock.AcquireReaderLock(-1);
                try
                {
                    hashtable = (Hashtable)OletxTransactionManager.resourceManagerHashTable.Clone();
                }
                finally
                {
                    OletxTransactionManager.resourceManagerHashTableLock.ReleaseReaderLock();
                }
            }
            if (hashtable != null)
            {
                enumerator = hashtable.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    OletxResourceManager manager = (OletxResourceManager)enumerator.Value;
                    if (manager != null)
                    {
                        manager.TMDownFromInternalRM(this.oletxTm);
                    }
                }
            }
            this.oletxTm.dtcTransactionManagerLock.AcquireWriterLock(-1);
            try
            {
                this.oletxTm.ReinitializeProxy();
            }
            finally
            {
                this.oletxTm.dtcTransactionManagerLock.ReleaseWriterLock();
            }
            if (DiagnosticTrace.Verbose)
            {
                MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxInternalResourceManager.TMDown");
            }
        }
コード例 #28
0
        public static Transaction GetTransactionFromDtcTransaction(
            IDtcTransaction transactionNative
            )
        {
            if ( !TransactionManager._platformValidated ) TransactionManager.ValidatePlatform();

            bool tooLate = false;
            ITransactionShim transactionShim = null;
            Guid txIdentifier = Guid.Empty;
            OletxTransactionIsolationLevel oletxIsoLevel = OletxTransactionIsolationLevel.ISOLATIONLEVEL_SERIALIZABLE;
            OutcomeEnlistment outcomeEnlistment = null;
            RealOletxTransaction realTx = null;
            OletxTransaction oleTx = null;

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

            Transaction transaction = null;

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

            // Let's get the guid of the transaction from the proxy to see if we already
            // have an object.
            ITransactionNativeInternal myTransactionNative = transactionNative as ITransactionNativeInternal;
            if ( null == myTransactionNative )
            {
                throw new ArgumentException( SR.GetString( SR.InvalidArgument ), "transactionNative" );
            }

            OletxXactTransInfo xactInfo;
            try
            {
                myTransactionNative.GetTransactionInfo( out xactInfo );
            }
            catch ( COMException ex )
            {
                if ( Oletx.NativeMethods.XACT_E_NOTRANSACTION != ex.ErrorCode )
                {
                    throw;
                }

                // If we get here, the transaction has appraently already been committed or aborted.  Allow creation of the
                // OletxTransaction, but it will be marked with a status of InDoubt and attempts to get its Identifier
                // property will result in a TransactionException.
                tooLate = true;
                xactInfo.uow = Guid.Empty;

            }

            OletxTransactionManager oletxTm = TransactionManager.DistributedTransactionManager;
            if ( ! tooLate )
            {
                // First check to see if there is a promoted LTM transaction with the same ID.  If there
                // is, just return that.
                transaction = TransactionManager.FindPromotedTransaction( xactInfo.uow );
                if ( null != transaction )
                {
                    if ( DiagnosticTrace.Verbose )
                    {
                        MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                            "TransactionInterop.GetTransactionFromDtcTransaction"
                            );
                    }
                    return transaction;
                }

                // We need to create a new RealOletxTransaction...
                oletxTm.dtcTransactionManagerLock.AcquireReaderLock( -1 );
                try
                {
                    outcomeEnlistment = new OutcomeEnlistment();
                    IntPtr outcomeEnlistmentHandle = IntPtr.Zero;
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try
                    {
                        outcomeEnlistmentHandle = HandleTable.AllocHandle( outcomeEnlistment );
                        oletxTm.DtcTransactionManager.ProxyShimFactory.CreateTransactionShim(
                            transactionNative,
                            outcomeEnlistmentHandle,
                            out txIdentifier,
                            out oletxIsoLevel,
                            out transactionShim );
                    }
                    finally
                    {
                        if ( transactionShim == null && outcomeEnlistmentHandle != IntPtr.Zero )
                        {
                            HandleTable.FreeHandle( outcomeEnlistmentHandle );
                        }
                    }
                }
                catch ( COMException comException )
                {
                    OletxTransactionManager.ProxyException( comException );
                    throw;
                }
                finally
                {
                    oletxTm.dtcTransactionManagerLock.ReleaseReaderLock();
                }

                // We need to create a new RealOletxTransaction.
                realTx = new RealOletxTransaction(
                    oletxTm,
                    transactionShim,
                    outcomeEnlistment,
                    txIdentifier,
                    oletxIsoLevel,
                    false );

                oleTx = new OletxTransaction( realTx );

                // If a transaction is found then FindOrCreate will Dispose the oletx
                // created.
                transaction = TransactionManager.FindOrCreatePromotedTransaction( xactInfo.uow, oleTx );
            }
            else
            {
                // It was too late to do a clone of the provided ITransactionNative, so we are just going to
                // create a RealOletxTransaction without a transaction shim or outcome enlistment.
                realTx = new RealOletxTransaction(
                    oletxTm,
                    null,
                    null,
                    txIdentifier,
                    OletxTransactionIsolationLevel.ISOLATIONLEVEL_SERIALIZABLE,
                    false );

                oleTx = new OletxTransaction( realTx );
                transaction = new Transaction( oleTx );
                TransactionManager.FireDistributedTransactionStarted( transaction );
                oleTx.savedLtmPromotedTransaction = transaction;

                InternalTransaction.DistributedTransactionOutcome(transaction.internalTransaction, TransactionStatus.InDoubt);
            }


            if ( DiagnosticTrace.Verbose )
            {
                MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    "TransactionInterop.GetTransactionFromDtc"
                    );
            }
            return transaction;
        }