CreateInvalidOperationException() static private méthode

static private CreateInvalidOperationException ( TraceSourceType traceSource, string message, Exception innerException ) : Exception
traceSource TraceSourceType
message string
innerException Exception
Résultat Exception
        internal static void DistributedTransactionOutcome(InternalTransaction tx, TransactionStatus status)
        {
            FinalizedObject finalizedObject = null;

            lock (tx)
            {
                if (tx.innerException == null)
                {
                    tx.innerException = tx.PromotedTransaction.InnerException;
                }
                switch (status)
                {
                case TransactionStatus.Committed:
                    tx.State.ChangeStatePromotedCommitted(tx);
                    break;

                case TransactionStatus.Aborted:
                    tx.State.ChangeStatePromotedAborted(tx);
                    break;

                case TransactionStatus.InDoubt:
                    tx.State.InDoubtFromDtc(tx);
                    break;

                default:
                    TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceLtm"), "", null);
                    break;
                }
                finalizedObject = tx.finalizedObject;
            }
            if (finalizedObject != null)
            {
                finalizedObject.Dispose();
            }
        }
Exemple #2
0
        internal int Add(InternalTransaction txNew)
        {
            Thread.BeginCriticalRegion();
            int num = 0;

            try
            {
                num = this.rwLock.AcquireReaderLock();
                try
                {
                    if ((txNew.AbsoluteTimeout != 0x7fffffffffffffffL) && !this.timerEnabled)
                    {
                        if (!this.timer.Change(this.timerInterval, this.timerInterval))
                        {
                            throw TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceLtm"), System.Transactions.SR.GetString("UnexpectedTimerFailure"), null);
                        }
                        this.lastTimerTime = DateTime.UtcNow.Ticks;
                        this.timerEnabled  = true;
                    }
                    txNew.CreationTime = this.CurrentTime;
                    this.AddIter(txNew);
                }
                finally
                {
                    this.rwLock.ReleaseReaderLock();
                }
            }
            finally
            {
                Thread.EndCriticalRegion();
            }
            return(num);
        }
Exemple #3
0
        protected static void PoolableInDoubt(object state)
        {
            VolatileDemultiplexer demultiplexer = (VolatileDemultiplexer)state;
            bool lockTaken = false;

            try
            {
                Monitor.TryEnter(demultiplexer.transaction, 250, ref lockTaken);
                if (lockTaken)
                {
                    demultiplexer.InternalInDoubt();
                }
                else if (!ThreadPool.QueueUserWorkItem(InDoubtCallback, demultiplexer))
                {
                    throw TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceLtm"), System.Transactions.SR.GetString("UnexpectedFailureOfThreadPool"), null);
                }
            }
            finally
            {
                if (lockTaken)
                {
                    Monitor.Exit(demultiplexer.transaction);
                }
            }
        }
Exemple #4
0
        internal OletxTransaction PSPEPromote(InternalTransaction tx)
        {
            TransactionState state = tx.State;

            base.CommonEnterState(tx);
            OletxTransaction oletxTransactionFromTransmitterPropigationToken = null;

            try
            {
                byte[] propagationToken = tx.promoter.Promote();
                if (propagationToken == null)
                {
                    throw TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceLtm"), System.Transactions.SR.GetString("PromotedReturnedInvalidValue"), null);
                }
                try
                {
                    oletxTransactionFromTransmitterPropigationToken = TransactionInterop.GetOletxTransactionFromTransmitterPropigationToken(propagationToken);
                }
                catch (ArgumentException exception)
                {
                    throw TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceLtm"), System.Transactions.SR.GetString("PromotedReturnedInvalidValue"), exception);
                }
                if (TransactionManager.FindPromotedTransaction(oletxTransactionFromTransmitterPropigationToken.Identifier) != null)
                {
                    oletxTransactionFromTransmitterPropigationToken.Dispose();
                    throw TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceLtm"), System.Transactions.SR.GetString("PromotedTransactionExists"), null);
                }
            }
            finally
            {
                state.CommonEnterState(tx);
            }
            return(oletxTransactionFromTransmitterPropigationToken);
        }
 internal override void EnterState(InternalTransaction tx)
 {
     base.EnterState(tx);
     base.CommonEnterState(tx);
     if (!ThreadPool.QueueUserWorkItem(SignalMethod, tx))
     {
         throw TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceLtm"), System.Transactions.SR.GetString("UnexpectedFailureOfThreadPool"), null);
     }
 }
Exemple #6
0
        internal static void DistributedTransactionOutcome(InternalTransaction tx, TransactionStatus status)
        {
            FinalizedObject?fo = null;

            lock (tx)
            {
                if (null == tx._innerException)
                {
                    Debug.Assert(tx.PromotedTransaction != null);
                    tx._innerException = tx.PromotedTransaction.InnerException;
                }

                Debug.Assert(tx.State ! != null);
                switch (status)
                {
                case TransactionStatus.Committed:
                {
                    tx.State.ChangeStatePromotedCommitted(tx);
                    break;
                }

                case TransactionStatus.Aborted:
                {
                    tx.State.ChangeStatePromotedAborted(tx);
                    break;
                }

                case TransactionStatus.InDoubt:
                {
                    tx.State.InDoubtFromDtc(tx);
                    break;
                }

                default:
                {
                    Debug.Fail("InternalTransaction.DistributedTransactionOutcome - Unexpected TransactionStatus");
                    TransactionException.CreateInvalidOperationException(TraceSourceType.TraceSourceLtm,
                                                                         "",
                                                                         null,
                                                                         tx.DistributedTxId
                                                                         );
                    break;
                }
                }

                fo = tx._finalizedObject;
            }

            if (null != fo)
            {
                fo.Dispose();
            }
        }
        internal static void DistributedTransactionOutcome(InternalTransaction tx, TransactionStatus status)
        {
            FinalizedObject fo = null;

            lock ( tx )
            {
                if (null == tx.innerException)
                {
                    tx.innerException = tx.PromotedTransaction.InnerException;
                }

                switch (status)
                {
                case TransactionStatus.Committed:
                {
                    tx.State.ChangeStatePromotedCommitted(tx);
                    break;
                }

                case TransactionStatus.Aborted:
                {
                    tx.State.ChangeStatePromotedAborted(tx);
                    break;
                }

                case TransactionStatus.InDoubt:
                {
                    tx.State.InDoubtFromDtc(tx);
                    break;
                }

                default:
                {
                    Debug.Assert(false, "InternalTransaction.DistributedTransactionOutcome - Unexpected TransactionStatus");
                    TransactionException.CreateInvalidOperationException(SR.GetString(SR.TraceSourceLtm),
                                                                         "",
                                                                         null
                                                                         );
                    break;
                }
                }

                fo = tx.finalizedObject;
            }

            if (null != fo)
            {
                fo.Dispose();
            }
        }
Exemple #8
0
        internal override void EnterState(InternalTransaction tx)
        {
            if (tx.outcomeSource.isoLevel == IsolationLevel.Snapshot)
            {
                throw TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceLtm"), System.Transactions.SR.GetString("CannotPromoteSnapshot"), null);
            }
            base.CommonEnterState(tx);
            OletxTransaction transaction = null;

            try
            {
                if (DiagnosticTrace.Verbose && (tx.durableEnlistment != null))
                {
                    EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceLtm"), tx.durableEnlistment.EnlistmentTraceId, NotificationCall.Promote);
                }
                transaction = TransactionState._TransactionStatePSPEOperation.PSPEPromote(tx);
            }
            catch (TransactionPromotionException exception)
            {
                tx.innerException = exception;
                if (DiagnosticTrace.Verbose)
                {
                    ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceLtm"), exception);
                }
            }
            finally
            {
                if (transaction == null)
                {
                    tx.State.ChangeStateAbortedDuringPromotion(tx);
                }
            }
            if (transaction != null)
            {
                tx.PromotedTransaction = transaction;
                Hashtable promotedTransactionTable = TransactionManager.PromotedTransactionTable;
                lock (promotedTransactionTable)
                {
                    tx.finalizedObject = new FinalizedObject(tx, tx.PromotedTransaction.Identifier);
                    WeakReference reference = new WeakReference(tx.outcomeSource, false);
                    promotedTransactionTable[tx.PromotedTransaction.Identifier] = reference;
                }
                TransactionManager.FireDistributedTransactionStarted(tx.outcomeSource);
                if (DiagnosticTrace.Information)
                {
                    TransactionPromotedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceLtm"), tx.TransactionTraceId, transaction.TransactionTraceId);
                }
                this.PromoteEnlistmentsAndOutcome(tx);
            }
        }
        // Add a transaction to the table.  Transactions are added to the end of the list in sorted order based on their
        // absolute timeout.
        internal int Add(InternalTransaction txNew)
        {
            // Tell the runtime that we are modifying global state.
            Thread.BeginCriticalRegion();
            int readerIndex = 0;

            try
            {
                readerIndex = rwLock.AcquireReaderLock();
                try
                {
                    // Start the timer if needed before checking the current time since the current
                    // time can be more efficient with a running timer.
                    if (txNew.AbsoluteTimeout != long.MaxValue)
                    {
                        if (!this.timerEnabled)
                        {
                            if (!this.timer.Change(this.timerInterval, this.timerInterval))
                            {
                                throw TransactionException.CreateInvalidOperationException(
                                          SR.GetString(SR.TraceSourceLtm),
                                          SR.GetString(SR.UnexpectedTimerFailure),
                                          null
                                          );
                            }
                            this.lastTimerTime = DateTime.UtcNow.Ticks;
                            this.timerEnabled  = true;
                        }
                    }
                    txNew.CreationTime = CurrentTime;

                    AddIter(txNew);
                }
                finally
                {
                    rwLock.ReleaseReaderLock();
                }
            }
            finally
            {
                Thread.EndCriticalRegion();
            }

            return(readerIndex);
        }
 public void Complete()
 {
     if (DiagnosticTrace.Verbose)
     {
         MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceBase"), "TransactionScope.Complete");
     }
     if (this.disposed)
     {
         throw new ObjectDisposedException("TransactionScope");
     }
     if (this.complete)
     {
         throw TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceBase"), System.Transactions.SR.GetString("DisposeScope"), null);
     }
     this.complete = true;
     if (DiagnosticTrace.Verbose)
     {
         MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceBase"), "TransactionScope.Complete");
     }
 }
Exemple #11
0
        // Add a transaction to the table.  Transactions are added to the end of the list in sorted order based on their
        // absolute timeout.
        internal int Add(InternalTransaction txNew)
        {
            // Tell the runtime that we are modifying global state.
            int readerIndex = 0;

            readerIndex = _rwLock.EnterReadLock();
            try
            {
                // Start the timer if needed before checking the current time since the current
                // time can be more efficient with a running timer.
                if (txNew.AbsoluteTimeout != long.MaxValue)
                {
                    if (!_timerEnabled)
                    {
                        if (!_timer.Change(_timerInterval, _timerInterval))
                        {
                            throw TransactionException.CreateInvalidOperationException(
                                      SR.TraceSourceLtm,
                                      SR.UnexpectedTimerFailure,
                                      null
                                      );
                        }
                        _lastTimerTime = DateTime.UtcNow.Ticks;
                        _timerEnabled  = true;
                    }
                }
                txNew.CreationTime = CurrentTime;

                AddIter(txNew);
            }
            finally
            {
                _rwLock.ExitReadLock();
            }

            return(readerIndex);
        }
Exemple #12
0
        protected static void PoolablePrepare(object state)
        {
            VolatileDemultiplexer demux = (VolatileDemultiplexer)state;

            // Don't block an enlistment thread (or a thread pool thread).  So
            // try to get the transaction lock but if unsuccessfull give up and
            // queue this operation to try again later.
            bool tookLock = false;

            try
            {
                Monitor.TryEnter(demux._transaction, 250, ref tookLock);
                if (tookLock)
                {
                    demux.InternalPrepare();
                }
                else
                {
                    if (!ThreadPool.QueueUserWorkItem(PrepareCallback, demux))
                    {
                        throw TransactionException.CreateInvalidOperationException(
                                  SR.TraceSourceLtm,
                                  SR.UnexpectedFailureOfThreadPool,
                                  null
                                  );
                    }
                }
            }
            finally
            {
                if (tookLock)
                {
                    Monitor.Exit(demux._transaction);
                }
            }
        }
Exemple #13
0
        public void Complete()
        {
            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceBase, this);
            }
            if (_disposed)
            {
                throw new ObjectDisposedException(nameof(TransactionScope));
            }

            if (_complete)
            {
                throw TransactionException.CreateInvalidOperationException(TraceSourceType.TraceSourceBase, SR.DisposeScope, null);
            }

            _complete = true;
            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceBase, this);
            }
        }
 // Override of get_RecoveryInformation to be more specific with the exception string.
 internal override byte[] RecoveryInformation(InternalEnlistment enlistment)
 {
     throw TransactionException.CreateInvalidOperationException(SR.TraceSourceLtm,
                                                                SR.VolEnlistNoRecoveryInfo, null, enlistment == null ? Guid.Empty : enlistment.DistributedTxId);
 }
Exemple #15
0
        // We don't have a finalizer (~TransactionScope) because all it would be able to do is try to
        // operate on other managed objects (the transaction), which is not safe to do because they may
        // already have been finalized.

        public void Dispose()
        {
            bool successful = false;

            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.MethodEnter(TraceSourceType.TraceSourceBase, this);
            }
            if (_disposed)
            {
                if (etwLog.IsEnabled())
                {
                    etwLog.MethodExit(TraceSourceType.TraceSourceBase, this);
                }
                return;
            }

            // Dispose for a scope can only be called on the thread where the scope was created.
            if ((_scopeThread != Thread.CurrentThread) && !AsyncFlowEnabled)
            {
                if (etwLog.IsEnabled())
                {
                    etwLog.InvalidOperation("TransactionScope", "InvalidScopeThread");
                }

                throw new InvalidOperationException(SR.InvalidScopeThread);
            }

            Exception exToThrow = null;

            try
            {
                // Single threaded from this point
                _disposed = true;

                // First, lets pop the "stack" of TransactionScopes and dispose each one that is above us in
                // the stack, making sure they are NOT consistent before disposing them.

                // Optimize the first lookup by getting both the actual current scope and actual current
                // transaction at the same time.
                TransactionScope actualCurrentScope = _threadContextData.CurrentScope;
                Transaction      contextTransaction = null;
                Transaction      current            = Transaction.FastGetTransaction(actualCurrentScope, _threadContextData, out contextTransaction);

                if (!Equals(actualCurrentScope))
                {
                    // Ok this is bad.  But just how bad is it.  The worst case scenario is that someone is
                    // poping scopes out of order and has placed a new transaction in the top level scope.
                    // Check for that now.
                    if (actualCurrentScope == null)
                    {
                        // Something must have gone wrong trying to clean up a bad scope
                        // stack previously.
                        // Make a best effort to abort the active transaction.
                        Transaction rollbackTransaction = _committableTransaction;
                        if (rollbackTransaction == null)
                        {
                            rollbackTransaction = _dependentTransaction;
                        }
                        Debug.Assert(rollbackTransaction != null);
                        rollbackTransaction.Rollback();

                        successful = true;
                        throw TransactionException.CreateInvalidOperationException(
                                  TraceSourceType.TraceSourceBase, SR.TransactionScopeInvalidNesting, null, rollbackTransaction.DistributedTxId);
                    }
                    // Verify that expectedCurrent is the same as the "current" current if we the interopOption value is None.
                    else if (EnterpriseServicesInteropOption.None == actualCurrentScope._interopOption)
                    {
                        if (((null != actualCurrentScope._expectedCurrent) && (!actualCurrentScope._expectedCurrent.Equals(current)))
                            ||
                            ((null != current) && (null == actualCurrentScope._expectedCurrent))
                            )
                        {
                            TransactionTraceIdentifier myId;
                            TransactionTraceIdentifier currentId;

                            if (null == current)
                            {
                                currentId = TransactionTraceIdentifier.Empty;
                            }
                            else
                            {
                                currentId = current.TransactionTraceId;
                            }

                            if (null == _expectedCurrent)
                            {
                                myId = TransactionTraceIdentifier.Empty;
                            }
                            else
                            {
                                myId = _expectedCurrent.TransactionTraceId;
                            }

                            if (etwLog.IsEnabled())
                            {
                                etwLog.TransactionScopeCurrentChanged(currentId, myId);
                            }

                            exToThrow = TransactionException.CreateInvalidOperationException(TraceSourceType.TraceSourceBase, SR.TransactionScopeIncorrectCurrent, null,
                                                                                             current == null ? Guid.Empty : current.DistributedTxId);

                            // If there is a current transaction, abort it.
                            if (null != current)
                            {
                                try
                                {
                                    current.Rollback();
                                }
                                catch (TransactionException)
                                {
                                    // we are already going to throw and exception, so just ignore this one.
                                }
                                catch (ObjectDisposedException)
                                {
                                    // Dito
                                }
                            }
                        }
                    }

                    // Now fix up the scopes
                    while (!Equals(actualCurrentScope))
                    {
                        if (null == exToThrow)
                        {
                            exToThrow = TransactionException.CreateInvalidOperationException(TraceSourceType.TraceSourceBase, SR.TransactionScopeInvalidNesting, null,
                                                                                             current == null ? Guid.Empty : current.DistributedTxId);
                        }

                        if (null == actualCurrentScope._expectedCurrent)
                        {
                            if (etwLog.IsEnabled())
                            {
                                etwLog.TransactionScopeNestedIncorrectly(TransactionTraceIdentifier.Empty);
                            }
                        }
                        else
                        {
                            if (etwLog.IsEnabled())
                            {
                                etwLog.TransactionScopeNestedIncorrectly(actualCurrentScope._expectedCurrent.TransactionTraceId);
                            }
                        }

                        actualCurrentScope._complete = false;
                        try
                        {
                            actualCurrentScope.InternalDispose();
                        }
                        catch (TransactionException)
                        {
                            // we are already going to throw an exception, so just ignore this one.
                        }

                        actualCurrentScope = _threadContextData.CurrentScope;

                        // We want to fail this scope, too, because work may have been done in one of these other
                        // nested scopes that really should have been done in my scope.
                        _complete = false;
                    }
                }
                else
                {
                    // Verify that expectedCurrent is the same as the "current" current if we the interopOption value is None.
                    // If we got here, actualCurrentScope is the same as "this".
                    if (EnterpriseServicesInteropOption.None == _interopOption)
                    {
                        if (((null != _expectedCurrent) && (!_expectedCurrent.Equals(current))) ||
                            ((null != current) && (null == _expectedCurrent))
                            )
                        {
                            TransactionTraceIdentifier myId;
                            TransactionTraceIdentifier currentId;

                            if (null == current)
                            {
                                currentId = TransactionTraceIdentifier.Empty;
                            }
                            else
                            {
                                currentId = current.TransactionTraceId;
                            }

                            if (null == _expectedCurrent)
                            {
                                myId = TransactionTraceIdentifier.Empty;
                            }
                            else
                            {
                                myId = _expectedCurrent.TransactionTraceId;
                            }

                            if (etwLog.IsEnabled())
                            {
                                etwLog.TransactionScopeCurrentChanged(currentId, myId);
                            }

                            if (null == exToThrow)
                            {
                                exToThrow = TransactionException.CreateInvalidOperationException(TraceSourceType.TraceSourceBase, SR.TransactionScopeIncorrectCurrent, null,
                                                                                                 current == null ? Guid.Empty : current.DistributedTxId);
                            }

                            // If there is a current transaction, abort it.
                            if (null != current)
                            {
                                try
                                {
                                    current.Rollback();
                                }
                                catch (TransactionException)
                                {
                                    // we are already going to throw and exception, so just ignore this one.
                                }
                                catch (ObjectDisposedException)
                                {
                                    // Dito
                                }
                            }
                            // Set consistent to false so that the subsequent call to
                            // InternalDispose below will rollback this.expectedCurrent.
                            _complete = false;
                        }
                    }
                }
                successful = true;
            }
            finally
            {
                if (!successful)
                {
                    PopScope();
                }
            }

            // No try..catch here.  Just let any exception thrown by InternalDispose go out.
            InternalDispose();

            if (null != exToThrow)
            {
                throw exToThrow;
            }

            if (etwLog.IsEnabled())
            {
                etwLog.MethodExit(TraceSourceType.TraceSourceBase, this);
            }
        }
Exemple #16
0
        // Process a timer event
        private void ThreadTimer(Object state)
        {
            //
            // Theory of operation.
            //
            // To timeout transactions we must walk down the list starting from the head
            // until we find a link with an absolute timeout that is greater than our own.
            // At that point everything further down in the list is elegable to be timed
            // out.  So simply remove that link in the list and walk down from that point
            // timing out any transaction that is found.
            //

            // There could be a race between this callback being queued and the timer
            // being disabled.  If we get here when the timer is disabled, just return.
            if (!_timerEnabled)
            {
                return;
            }

            // Increment the number of ticks
            _ticks++;
            _lastTimerTime = DateTime.UtcNow.Ticks;

            //
            // First find the starting point of transactions that should time out.  Every transaction after
            // that point will timeout so once we've found it then it is just a matter of traversing the
            // structure.
            //
            BucketSet lastBucketSet    = null;
            BucketSet currentBucketSet = _headBucketSet; // The list always has a head.

            // Acquire a writer lock before checking to see if we should disable the timer.
            // Adding of transactions acquires a reader lock and might insert a new BucketSet.
            // If that races with our check for a BucketSet existing, we may not timeout that
            // transaction that is being added.
            WeakReference nextWeakSet   = null;
            BucketSet     nextBucketSet = null;

            nextWeakSet = (WeakReference)currentBucketSet.nextSetWeak;
            if (nextWeakSet != null)
            {
                nextBucketSet = (BucketSet)nextWeakSet.Target;
            }

            if (nextBucketSet == null)
            {
                _rwLock.EnterWriteLock();
                try
                {
                    // Access the nextBucketSet again in writer lock to account for any race before disabling the timeout.
                    nextWeakSet = (WeakReference)currentBucketSet.nextSetWeak;
                    if (nextWeakSet != null)
                    {
                        nextBucketSet = (BucketSet)nextWeakSet.Target;
                    }

                    if (nextBucketSet == null)
                    {
                        //
                        // Special case to allow for disabling the timer.
                        //
                        // If there are no transactions on the timeout list we can disable the
                        // timer.
                        if (!_timer.Change(Timeout.Infinite, Timeout.Infinite))
                        {
                            throw TransactionException.CreateInvalidOperationException(
                                      SR.TraceSourceLtm,
                                      SR.UnexpectedTimerFailure,
                                      null
                                      );
                        }
                        _timerEnabled = false;

                        return;
                    }
                }
                finally
                {
                    _rwLock.ExitWriteLock();
                }
            }

            // Note it is slightly subtle that we always skip the head node.  This is done
            // on purpose because the head node contains transactions with essentially
            // an infinite timeout.
            do
            {
                do
                {
                    nextWeakSet = (WeakReference)currentBucketSet.nextSetWeak;
                    if (nextWeakSet == null)
                    {
                        // Nothing more to do.
                        return;
                    }

                    nextBucketSet = (BucketSet)nextWeakSet.Target;
                    if (nextBucketSet == null)
                    {
                        // Again nothing more to do.
                        return;
                    }
                    lastBucketSet    = currentBucketSet;
                    currentBucketSet = nextBucketSet;
                }while (currentBucketSet.AbsoluteTimeout > _ticks);

                //
                // Pinch off the list at this point making sure it is still the correct set.
                //
                // Note: We may lose a race with an "Add" thread that is inserting a BucketSet in this location in
                // the list. If that happens, this CompareExchange will not be performed and the returned abortingSetsWeak
                // value will NOT equal nextWeakSet. But we check for that and if this condition occurs, this iteration of
                // the timer thread will simply return, not timing out any transactions. When the next timer interval
                // expires, the thread will walk the list again, find the appropriate BucketSet to pinch off, and
                // then time out the transactions. This means that it is possible for a transaction to live a bit longer,
                // but not much.
                WeakReference abortingSetsWeak =
                    (WeakReference)Interlocked.CompareExchange(ref lastBucketSet.nextSetWeak, null, nextWeakSet);

                if (abortingSetsWeak == nextWeakSet)
                {
                    // Yea - now proceed to abort the transactions.
                    BucketSet abortingBucketSets = null;

                    do
                    {
                        if (abortingSetsWeak != null)
                        {
                            abortingBucketSets = (BucketSet)abortingSetsWeak.Target;
                        }
                        else
                        {
                            abortingBucketSets = null;
                        }
                        if (abortingBucketSets != null)
                        {
                            abortingBucketSets.TimeoutTransactions();
                            abortingSetsWeak = (WeakReference)abortingBucketSets.nextSetWeak;
                        }
                    }while (abortingBucketSets != null);

                    // That's all we needed to do.
                    break;
                }

                // We missed pulling the right transactions off.  Loop back up and try again.
                currentBucketSet = lastBucketSet;
            }while (true);
        }
        public void Dispose()
        {
            bool flag = false;

            if (DiagnosticTrace.Verbose)
            {
                MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceBase"), "TransactionScope.Dispose");
            }
            if (this.disposed)
            {
                if (DiagnosticTrace.Verbose)
                {
                    MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceBase"), "TransactionScope.Dispose");
                }
            }
            else
            {
                if (this.scopeThread != Thread.CurrentThread)
                {
                    if (DiagnosticTrace.Error)
                    {
                        InvalidOperationExceptionTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceBase"), System.Transactions.SR.GetString("InvalidScopeThread"));
                    }
                    throw new InvalidOperationException(System.Transactions.SR.GetString("InvalidScopeThread"));
                }
                Exception exception = null;
                try
                {
                    this.disposed = true;
                    TransactionScope currentScope       = this.threadContextData.CurrentScope;
                    Transaction      contextTransaction = null;
                    Transaction      transaction        = Transaction.FastGetTransaction(currentScope, this.threadContextData, out contextTransaction);
                    if (!this.Equals(currentScope))
                    {
                        if (currentScope == null)
                        {
                            Transaction committableTransaction = this.committableTransaction;
                            if (committableTransaction == null)
                            {
                                committableTransaction = this.dependentTransaction;
                            }
                            committableTransaction.Rollback();
                            flag = true;
                            throw TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceBase"), System.Transactions.SR.GetString("TransactionScopeInvalidNesting"), null);
                        }
                        if ((currentScope.interopOption == EnterpriseServicesInteropOption.None) && (((null != currentScope.expectedCurrent) && !currentScope.expectedCurrent.Equals(transaction)) || ((null != transaction) && (null == currentScope.expectedCurrent))))
                        {
                            if (DiagnosticTrace.Warning)
                            {
                                TransactionTraceIdentifier transactionTraceId;
                                TransactionTraceIdentifier empty;
                                if (null == transaction)
                                {
                                    empty = TransactionTraceIdentifier.Empty;
                                }
                                else
                                {
                                    empty = transaction.TransactionTraceId;
                                }
                                if (null == this.expectedCurrent)
                                {
                                    transactionTraceId = TransactionTraceIdentifier.Empty;
                                }
                                else
                                {
                                    transactionTraceId = this.expectedCurrent.TransactionTraceId;
                                }
                                TransactionScopeCurrentChangedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceBase"), transactionTraceId, empty);
                            }
                            exception = TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceBase"), System.Transactions.SR.GetString("TransactionScopeIncorrectCurrent"), null);
                            if (null != transaction)
                            {
                                try
                                {
                                    transaction.Rollback();
                                }
                                catch (TransactionException)
                                {
                                }
                                catch (ObjectDisposedException)
                                {
                                }
                            }
                        }
                        while (!this.Equals(currentScope))
                        {
                            if (exception == null)
                            {
                                exception = TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceBase"), System.Transactions.SR.GetString("TransactionScopeInvalidNesting"), null);
                            }
                            if (DiagnosticTrace.Warning)
                            {
                                if (null == currentScope.expectedCurrent)
                                {
                                    TransactionScopeNestedIncorrectlyTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceBase"), TransactionTraceIdentifier.Empty);
                                }
                                else
                                {
                                    TransactionScopeNestedIncorrectlyTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceBase"), currentScope.expectedCurrent.TransactionTraceId);
                                }
                            }
                            currentScope.complete = false;
                            try
                            {
                                currentScope.InternalDispose();
                            }
                            catch (TransactionException)
                            {
                            }
                            currentScope  = this.threadContextData.CurrentScope;
                            this.complete = false;
                        }
                    }
                    else if ((this.interopOption == EnterpriseServicesInteropOption.None) && (((null != this.expectedCurrent) && !this.expectedCurrent.Equals(transaction)) || ((null != transaction) && (null == this.expectedCurrent))))
                    {
                        if (DiagnosticTrace.Warning)
                        {
                            TransactionTraceIdentifier identifier;
                            TransactionTraceIdentifier identifier2;
                            if (null == transaction)
                            {
                                identifier2 = TransactionTraceIdentifier.Empty;
                            }
                            else
                            {
                                identifier2 = transaction.TransactionTraceId;
                            }
                            if (null == this.expectedCurrent)
                            {
                                identifier = TransactionTraceIdentifier.Empty;
                            }
                            else
                            {
                                identifier = this.expectedCurrent.TransactionTraceId;
                            }
                            TransactionScopeCurrentChangedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceBase"), identifier, identifier2);
                        }
                        if (exception == null)
                        {
                            exception = TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceBase"), System.Transactions.SR.GetString("TransactionScopeIncorrectCurrent"), null);
                        }
                        if (null != transaction)
                        {
                            try
                            {
                                transaction.Rollback();
                            }
                            catch (TransactionException)
                            {
                            }
                            catch (ObjectDisposedException)
                            {
                            }
                        }
                        this.complete = false;
                    }
                    flag = true;
                }
                finally
                {
                    if (!flag)
                    {
                        this.PopScope();
                    }
                }
                this.InternalDispose();
                if (exception != null)
                {
                    throw exception;
                }
                if (DiagnosticTrace.Verbose)
                {
                    MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceBase"), "TransactionScope.Dispose");
                }
            }
        }
Exemple #18
0
        internal override void EnterState(InternalTransaction tx)
        {
            if (tx.outcomeSource.isoLevel == IsolationLevel.Snapshot)
            {
                throw TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceLtm"), System.Transactions.SR.GetString("CannotPromoteSnapshot"), null);
            }
            base.CommonEnterState(tx);
            OletxCommittableTransaction transaction = null;

            try
            {
                TimeSpan zero;
                if (tx.AbsoluteTimeout == 0x7fffffffffffffffL)
                {
                    zero = TimeSpan.Zero;
                }
                else
                {
                    zero = TransactionManager.TransactionTable.RecalcTimeout(tx);
                    if (zero <= TimeSpan.Zero)
                    {
                        return;
                    }
                }
                TransactionOptions properties = new TransactionOptions {
                    IsolationLevel = tx.outcomeSource.isoLevel,
                    Timeout        = zero
                };
                transaction = TransactionManager.DistributedTransactionManager.CreateTransaction(properties);
                transaction.savedLtmPromotedTransaction = tx.outcomeSource;
                if (DiagnosticTrace.Information)
                {
                    TransactionPromotedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceLtm"), tx.TransactionTraceId, transaction.TransactionTraceId);
                }
            }
            catch (TransactionException exception)
            {
                tx.innerException = exception;
                if (DiagnosticTrace.Verbose)
                {
                    ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceLtm"), exception);
                }
                return;
            }
            finally
            {
                if (transaction == null)
                {
                    tx.State.ChangeStateAbortedDuringPromotion(tx);
                }
            }
            tx.PromotedTransaction = transaction;
            Hashtable promotedTransactionTable = TransactionManager.PromotedTransactionTable;

            lock (promotedTransactionTable)
            {
                tx.finalizedObject = new FinalizedObject(tx, transaction.Identifier);
                WeakReference reference = new WeakReference(tx.outcomeSource, false);
                promotedTransactionTable[transaction.Identifier] = reference;
            }
            TransactionManager.FireDistributedTransactionStarted(tx.outcomeSource);
            this.PromoteEnlistmentsAndOutcome(tx);
        }
Exemple #19
0
        private void ThreadTimer(object state)
        {
            if (!this.timerEnabled)
            {
                return;
            }
            this.ticks        += 1L;
            this.lastTimerTime = DateTime.UtcNow.Ticks;
            BucketSet     set4          = null;
            BucketSet     headBucketSet = this.headBucketSet;
            WeakReference nextSetWeak   = (WeakReference)headBucketSet.nextSetWeak;
            BucketSet     target        = null;

            if (nextSetWeak != null)
            {
                target = (BucketSet)nextSetWeak.Target;
            }
            if (target == null)
            {
                this.rwLock.AcquireWriterLock();
                try
                {
                    if (!this.timer.Change(-1, -1))
                    {
                        throw TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceLtm"), System.Transactions.SR.GetString("UnexpectedTimerFailure"), null);
                    }
                    this.timerEnabled = false;
                    return;
                }
                finally
                {
                    this.rwLock.ReleaseWriterLock();
                }
            }
Label_00A0:
            nextSetWeak = (WeakReference)headBucketSet.nextSetWeak;
            if (nextSetWeak != null)
            {
                target = (BucketSet)nextSetWeak.Target;
                if (target != null)
                {
                    set4          = headBucketSet;
                    headBucketSet = target;
                    if (headBucketSet.AbsoluteTimeout <= this.ticks)
                    {
                        Thread.BeginCriticalRegion();
                        try
                        {
                            WeakReference reference2 = (WeakReference)Interlocked.CompareExchange(ref set4.nextSetWeak, null, nextSetWeak);
                            if (reference2 == nextSetWeak)
                            {
                                BucketSet set = null;
                                do
                                {
                                    if (reference2 != null)
                                    {
                                        set = (BucketSet)reference2.Target;
                                    }
                                    else
                                    {
                                        set = null;
                                    }
                                    if (set != null)
                                    {
                                        set.TimeoutTransactions();
                                        reference2 = (WeakReference)set.nextSetWeak;
                                    }
                                }while (set != null);
                                return;
                            }
                        }
                        finally
                        {
                            Thread.EndCriticalRegion();
                        }
                        headBucketSet = set4;
                    }
                    goto Label_00A0;
                }
            }
        }
Exemple #20
0
 internal override byte[] RecoveryInformation(InternalEnlistment enlistment)
 {
     throw TransactionException.CreateInvalidOperationException(System.Transactions.SR.GetString("TraceSourceLtm"), System.Transactions.SR.GetString("VolEnlistNoRecoveryInfo"), null);
 }