Beispiel #1
0
 internal DurableInternalEnlistment(
     Enlistment enlistment,
     Guid resourceManagerIdentifier,
     InternalTransaction transaction,
     IEnlistmentNotification twoPhaseNotifications,
     ISinglePhaseNotification singlePhaseNotifications,
     Transaction atomicTransaction) :
     base(enlistment, transaction, twoPhaseNotifications, singlePhaseNotifications, atomicTransaction)
 {
     _resourceManagerIdentifier = resourceManagerIdentifier;
 }
Beispiel #2
0
 internal InternalEnlistment(
     Enlistment enlistment,
     IEnlistmentNotification twoPhaseNotifications,
     InternalTransaction transaction,
     Transaction atomicTransaction)
 {
     _enlistment            = enlistment;
     _twoPhaseNotifications = twoPhaseNotifications;
     _transaction           = transaction;
     _atomicTransaction     = atomicTransaction;
 }
Beispiel #3
0
 internal Enlistment(
     IEnlistmentNotification twoPhaseNotifications,
     InternalTransaction transaction,
     Transaction atomicTransaction)
 {
     _internalEnlistment = new InternalEnlistment(
         this,
         twoPhaseNotifications,
         transaction,
         atomicTransaction
         );
 }
Beispiel #4
0
 // This constructor is for a promotable single phase enlistment.
 internal Enlistment(
     InternalTransaction transaction,
     IPromotableSinglePhaseNotification promotableSinglePhaseNotification,
     Transaction atomicTransaction)
 {
     _internalEnlistment = new PromotableInternalEnlistment(
         this,
         transaction,
         promotableSinglePhaseNotification,
         atomicTransaction
         );
 }
Beispiel #5
0
        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(TraceSourceType.TraceSourceLtm,
                                                                         "",
                                                                         null,
                                                                         tx.DistributedTxId
                                                                         );
                    break;
                }
                }

                fo = tx._finalizedObject;
            }

            if (null != fo)
            {
                fo.Dispose();
            }
        }
Beispiel #6
0
 internal InternalEnlistment(
     Enlistment enlistment,
     InternalTransaction transaction,
     IEnlistmentNotification twoPhaseNotifications,
     ISinglePhaseNotification singlePhaseNotifications,
     Transaction atomicTransaction)
 {
     _enlistment               = enlistment;
     _transaction              = transaction;
     _twoPhaseNotifications    = twoPhaseNotifications;
     _singlePhaseNotifications = singlePhaseNotifications;
     _atomicTransaction        = atomicTransaction;
     _enlistmentId             = transaction._enlistmentCount++;
     _traceIdentifier          = EnlistmentTraceIdentifier.Empty;
 }
Beispiel #7
0
 // Create a transaction with the given settings
 //
 internal DependentTransaction(IsolationLevel isoLevel, InternalTransaction internalTransaction, bool blocking) :
     base(isoLevel, internalTransaction)
 {
     _blocking = blocking;
     lock (_internalTransaction)
     {
         if (blocking)
         {
             _internalTransaction.State.CreateBlockingClone(_internalTransaction);
         }
         else
         {
             _internalTransaction.State.CreateAbortingClone(_internalTransaction);
         }
     }
 }
Beispiel #8
0
 internal Enlistment(
     Guid resourceManagerIdentifier,
     InternalTransaction transaction,
     IEnlistmentNotification twoPhaseNotifications,
     ISinglePhaseNotification singlePhaseNotifications,
     Transaction atomicTransaction)
 {
     _internalEnlistment = new DurableInternalEnlistment(
         this,
         resourceManagerIdentifier,
         transaction,
         twoPhaseNotifications,
         singlePhaseNotifications,
         atomicTransaction
         );
 }
Beispiel #9
0
        internal CommittableTransaction(IsolationLevel isoLevel, TimeSpan timeout) : base(isoLevel, (InternalTransaction)null)
        {
            // object to use for synchronization rather than locking on a public object
            _internalTransaction = new InternalTransaction(timeout, this)
            {
                // Because we passed null for the internal transaction to the base class, we need to
                // fill in the traceIdentifier field here.
                _cloneCount = 1
            };
            _cloneId = 1;
            TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                etwLog.TransactionCreated(this, "CommittableTransaction");
            }
        }
Beispiel #10
0
        internal void TimeoutTransactions()
        {
            int i;
            int transactionCount = _index;

            _timedOut = true;
            Interlocked.MemoryBarrier();

            for (i = 0; i <= transactionCount && i < _size; i++)
            {
                Debug.Assert(transactionCount == _index, "Index changed timing out transactions");
                InternalTransaction tx = _transactions[i];
                if (tx != null)
                {
                    lock (tx)
                    {
                        tx.State.Timeout(tx);
                    }
                }
            }
        }
Beispiel #11
0
        internal Transaction(IsolationLevel isoLevel, ISimpleTransactionSuperior superior)
        {
            TransactionManager.ValidateIsolationLevel(isoLevel);

            if (superior == null)
            {
                throw new ArgumentNullException(nameof(superior));
            }

            _isoLevel = isoLevel;

            // Never create a transaction with an IsolationLevel of Unspecified.
            if (IsolationLevel.Unspecified == _isoLevel)
            {
                _isoLevel = TransactionManager.DefaultIsolationLevel;
            }

            _internalTransaction = new InternalTransaction(this, superior);
            // ISimpleTransactionSuperior is defined to also promote to MSDTC.
            _internalTransaction.SetPromoterTypeToMSDTC();
            _cloneId = 1;
        }
Beispiel #12
0
        internal bool Add(InternalTransaction tx)
        {
            int currentIndex = Interlocked.Increment(ref _index);

            if (currentIndex < _size)
            {
                tx._tableBucket = this;
                tx._bucketIndex = currentIndex;
                Interlocked.MemoryBarrier(); // This data must be written before the transaction
                                             // could be timed out.
                _transactions[currentIndex] = tx;

                if (_timedOut)
                {
                    lock (tx)
                    {
                        tx.State.Timeout(tx);
                    }
                }
            }
            else
            {
                Bucket newBucket = new Bucket(_owningSet)
                {
                    nextBucketWeak = new WeakReference(this)
                };

                Bucket oldBucket = Interlocked.CompareExchange(ref _owningSet.headBucket, newBucket, this);
                if (oldBucket == this)
                {
                    // ladies and gentlemen we have a winner.
                    _previous = newBucket;
                }

                return(false);
            }
            return(true);
        }
Beispiel #13
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(
                                      TraceSourceType.TraceSourceLtm,
                                      SR.UnexpectedTimerFailure,
                                      null
                                      );
                        }
                        _lastTimerTime = DateTime.UtcNow.Ticks;
                        _timerEnabled  = true;
                    }
                }
                txNew.CreationTime = CurrentTime;

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

            return(readerIndex);
        }
Beispiel #14
0
        // Create a transaction with the given settings
        //
        internal Transaction(IsolationLevel isoLevel, InternalTransaction internalTransaction)
        {
            TransactionManager.ValidateIsolationLevel(isoLevel);

            _isoLevel = isoLevel;

            // Never create a transaction with an IsolationLevel of Unspecified.
            if (IsolationLevel.Unspecified == _isoLevel)
            {
                _isoLevel = TransactionManager.DefaultIsolationLevel;
            }

            if (internalTransaction != null)
            {
                _internalTransaction = internalTransaction;
                _cloneId             = Interlocked.Increment(ref _internalTransaction._cloneCount);
            }
            else
            {
                // Null is passed from the constructor of a CommittableTransaction.  That
                // constructor will fill in the traceIdentifier because it has allocated the
                // internal transaction.
            }
        }
Beispiel #15
0
 // Absolute timeout
 internal TimeSpan RecalcTimeout(InternalTransaction tx)
 {
     return(TimeSpan.FromMilliseconds((tx.AbsoluteTimeout - _ticks) * _timerInterval));
 }
Beispiel #16
0
 internal FinalizedObject(InternalTransaction internalTransaction, Guid identifier)
 {
     _internalTransaction = internalTransaction;
     _identifier          = identifier;
 }
 internal TransactionInformation(InternalTransaction internalTransaction)
 {
     _internalTransaction = internalTransaction;
 }
Beispiel #18
0
 public Phase1VolatileDemultiplexer(InternalTransaction transaction) : base(transaction)
 {
 }
Beispiel #19
0
 public VolatileDemultiplexer(InternalTransaction transaction)
 {
     _transaction = transaction;
 }
Beispiel #20
0
 internal void Remove(InternalTransaction tx)
 {
     _transactions[tx._bucketIndex] = null;
 }
Beispiel #21
0
 // Remove a transaction from the table.
 internal void Remove(InternalTransaction tx)
 {
     tx._tableBucket.Remove(tx);
     tx._tableBucket = null;
 }
Beispiel #22
0
        private void AddIter(InternalTransaction txNew)
        {
            //
            // Theory of operation.
            //
            // Note that the head bucket contains any transaction with essentially infinite
            // timeout (long.MaxValue).  The list is sorted in decending order.  To add
            // a node the code must walk down the list looking for a set of bucket that matches
            // the absolute timeout value for the transaction.  When it is found it passes
            // the insert down to that set.
            //
            // An importent thing to note about the list is that forward links are all weak
            // references and reverse links are all strong references.  This allows the GC
            // to clean up old links in the list so that they don't need to be removed manually.
            // However if there is still a rooted strong reference to an old link in the
            // chain that link won't fall off the list because there is a strong reference held
            // forward.
            //

            BucketSet currentBucketSet = _headBucketSet;

            while (currentBucketSet.AbsoluteTimeout != txNew.AbsoluteTimeout)
            {
                BucketSet lastBucketSet = null;
                do
                {
                    WeakReference nextSetWeak   = (WeakReference)currentBucketSet.nextSetWeak;
                    BucketSet     nextBucketSet = null;
                    if (nextSetWeak != null)
                    {
                        nextBucketSet = (BucketSet)nextSetWeak.Target;
                    }

                    if (nextBucketSet == null)
                    {
                        //
                        // We've reached the end of the list either because nextSetWeak was null or
                        // because its reference was collected.  This code doesn't care.  Make a new
                        // set, attempt to attach it and move on.
                        //
                        BucketSet     newBucketSet = new BucketSet(this, txNew.AbsoluteTimeout);
                        WeakReference newSetWeak   = new WeakReference(newBucketSet);

                        WeakReference oldNextSetWeak = (WeakReference)Interlocked.CompareExchange(
                            ref currentBucketSet.nextSetWeak, newSetWeak, nextSetWeak);
                        if (oldNextSetWeak == nextSetWeak)
                        {
                            // Ladies and Gentlemen we have a winner.
                            newBucketSet.prevSet = currentBucketSet;
                        }

                        // Note that at this point we don't update currentBucketSet.  On the next loop
                        // iteration we should be able to pick up where we left off.
                    }
                    else
                    {
                        lastBucketSet    = currentBucketSet;
                        currentBucketSet = nextBucketSet;
                    }
                }while (currentBucketSet.AbsoluteTimeout > txNew.AbsoluteTimeout);

                if (currentBucketSet.AbsoluteTimeout != txNew.AbsoluteTimeout)
                {
                    //
                    // Getting to here means that we've found a slot in the list where this bucket set should go.
                    //
                    BucketSet     newBucketSet = new BucketSet(this, txNew.AbsoluteTimeout);
                    WeakReference newSetWeak   = new WeakReference(newBucketSet);

                    newBucketSet.nextSetWeak = lastBucketSet.nextSetWeak;
                    WeakReference oldNextSetWeak = (WeakReference)Interlocked.CompareExchange(
                        ref lastBucketSet.nextSetWeak, newSetWeak, newBucketSet.nextSetWeak);
                    if (oldNextSetWeak == newBucketSet.nextSetWeak)
                    {
                        // Ladies and Gentlemen we have a winner.
                        if (oldNextSetWeak != null)
                        {
                            BucketSet oldSet = (BucketSet)oldNextSetWeak.Target;
                            if (oldSet != null)
                            {
                                // prev references are just there to root things for the GC.  If this object is
                                // gone we don't really care.
                                oldSet.prevSet = newBucketSet;
                            }
                        }
                        newBucketSet.prevSet = lastBucketSet;
                    }

                    // Special note - We are going to loop back to the BucketSet that preceeds the one we just tried
                    // to insert because we may have lost the race to insert our new BucketSet into the list to another
                    // "Add" thread. By looping back, we check again to see if the BucketSet we just created actually
                    // got added. If it did, we will exit out of the outer loop and add the transaction. But if we
                    // lost the race, we will again try to add a new BucketSet. In the latter case, the BucketSet
                    // we created during the first iteration will simply be Garbage Collected because there are no
                    // strong references to it since we never added the transaction to a bucket and the act of
                    // creating the second BucketSet with remove the backward reference that was created in the
                    // first trip thru the loop.
                    currentBucketSet = lastBucketSet;
                    lastBucketSet    = null;

                    // The outer loop will iterate and pick up where we left off.
                }
            }

            //
            // Great we found a spot.
            //
            currentBucketSet.Add(txNew);
        }
Beispiel #23
0
 internal Transaction(DistributedTransaction distributedTransaction)
 {
     _isoLevel            = distributedTransaction.IsolationLevel;
     _internalTransaction = new InternalTransaction(this, distributedTransaction);
     _cloneId             = Interlocked.Increment(ref _internalTransaction._cloneCount);
 }