internal InternalEnlistment( Enlistment enlistment, IEnlistmentNotification twoPhaseNotifications, InternalTransaction transaction, Transaction atomicTransaction) { _enlistment = enlistment; _twoPhaseNotifications = twoPhaseNotifications; _transaction = transaction; _atomicTransaction = atomicTransaction; }
internal DurableInternalEnlistment( Enlistment enlistment, Guid resourceManagerIdentifier, InternalTransaction transaction, IEnlistmentNotification twoPhaseNotifications, ISinglePhaseNotification singlePhaseNotifications, Transaction atomicTransaction) : base(enlistment, transaction, twoPhaseNotifications, singlePhaseNotifications, atomicTransaction) { _resourceManagerIdentifier = resourceManagerIdentifier; }
// This constructor is for a promotable single phase enlistment. internal Enlistment( InternalTransaction transaction, IPromotableSinglePhaseNotification promotableSinglePhaseNotification, Transaction atomicTransaction) { _internalEnlistment = new PromotableInternalEnlistment( this, transaction, promotableSinglePhaseNotification, atomicTransaction ); }
internal Enlistment( IEnlistmentNotification twoPhaseNotifications, InternalTransaction transaction, Transaction atomicTransaction) { _internalEnlistment = new InternalEnlistment( this, twoPhaseNotifications, transaction, atomicTransaction ); }
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(); } }
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; }
internal Enlistment( Guid resourceManagerIdentifier, InternalTransaction transaction, IEnlistmentNotification twoPhaseNotifications, ISinglePhaseNotification singlePhaseNotifications, Transaction atomicTransaction) { _internalEnlistment = new DurableInternalEnlistment( this, resourceManagerIdentifier, transaction, twoPhaseNotifications, singlePhaseNotifications, atomicTransaction ); }
// 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); } } }
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"); } }
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); } } } }
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; }
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); }
// 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); }
// 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. } }
public VolatileDemultiplexer(InternalTransaction transaction) { _transaction = transaction; }
internal Transaction(DistributedTransaction distributedTransaction) { _isoLevel = distributedTransaction.IsolationLevel; _internalTransaction = new InternalTransaction(this, distributedTransaction); _cloneId = Interlocked.Increment(ref _internalTransaction._cloneCount); }
internal TransactionInformation(InternalTransaction internalTransaction) { _internalTransaction = internalTransaction; }
// Absolute timeout internal TimeSpan RecalcTimeout(InternalTransaction tx) { return(TimeSpan.FromMilliseconds((tx.AbsoluteTimeout - _ticks) * _timerInterval)); }
internal FinalizedObject(InternalTransaction internalTransaction, Guid identifier) { _internalTransaction = internalTransaction; _identifier = identifier; }
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); }
// Remove a transaction from the table. internal void Remove(InternalTransaction tx) { tx._tableBucket.Remove(tx); tx._tableBucket = null; }
internal void Remove(InternalTransaction tx) { _transactions[tx._bucketIndex] = null; }
public Phase1VolatileDemultiplexer(InternalTransaction transaction) : base(transaction) { }