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"); } }
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" ); } }