internal DtcTransactionManager(string nodeName, OletxTransactionManager oletxTm) { this.nodeName = nodeName; this.oletxTm = oletxTm; this.initialized = false; this.proxyShimFactory = OletxTransactionManager.proxyShimFactory; }
internal DtcTransactionManager( string nodeName, OletxTransactionManager oletxTm ) { this.nodeName = nodeName; this.oletxTm = oletxTm; this.initialized = false; this.proxyShimFactory = OletxTransactionManager.proxyShimFactory; }
internal void Commit() { try { this.transactionShim.Commit(); } catch (COMException exception) { if ((System.Transactions.Oletx.NativeMethods.XACT_E_ABORTED == exception.ErrorCode) || (System.Transactions.Oletx.NativeMethods.XACT_E_INDOUBT == exception.ErrorCode)) { Interlocked.CompareExchange <Exception>(ref this.innerException, exception, null); if (DiagnosticTrace.Verbose) { ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception); } } else { if (System.Transactions.Oletx.NativeMethods.XACT_E_ALREADYINPROGRESS == exception.ErrorCode) { throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TransactionAlreadyOver"), exception); } OletxTransactionManager.ProxyException(exception); throw; } } }
private void Initialize() { if (!this.initialized) { OletxInternalResourceManager internalResourceManager = this.oletxTm.internalResourceManager; IntPtr zero = IntPtr.Zero; IResourceManagerShim resourceManagerShim = null; bool nodeNameMatches = false; CoTaskMemHandle whereaboutsBuffer = null; RuntimeHelpers.PrepareConstrainedRegions(); try { zero = HandleTable.AllocHandle(internalResourceManager); this.proxyShimFactory.ConnectToProxy(this.nodeName, internalResourceManager.Identifier, zero, out nodeNameMatches, out this.whereaboutsSize, out whereaboutsBuffer, out resourceManagerShim); if (!nodeNameMatches) { throw new NotSupportedException(System.Transactions.SR.GetString("ProxyCannotSupportMultipleNodeNames")); } if ((whereaboutsBuffer != null) && (this.whereaboutsSize != 0)) { this.whereabouts = new byte[this.whereaboutsSize]; Marshal.Copy(whereaboutsBuffer.DangerousGetHandle(), this.whereabouts, 0, Convert.ToInt32(this.whereaboutsSize)); } internalResourceManager.resourceManagerShim = resourceManagerShim; internalResourceManager.CallReenlistComplete(); this.initialized = true; } catch (COMException exception) { if (System.Transactions.Oletx.NativeMethods.XACT_E_NOTSUPPORTED == exception.ErrorCode) { throw new NotSupportedException(System.Transactions.SR.GetString("CannotSupportNodeNameSpecification")); } OletxTransactionManager.ProxyException(exception); throw TransactionManagerCommunicationException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TransactionManagerCommunicationException"), exception); } finally { if (whereaboutsBuffer != null) { whereaboutsBuffer.Close(); } if (!this.initialized) { if ((zero != IntPtr.Zero) && (resourceManagerShim == null)) { HandleTable.FreeHandle(zero); } if (this.whereabouts != null) { this.whereabouts = null; this.whereaboutsSize = 0; } } } } }
internal void Rollback() { lock (this) { if ((TransactionStatus.Aborted != this.status) && (this.status != TransactionStatus.Active)) { throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TransactionAlreadyOver"), null); } if (TransactionStatus.Aborted == this.status) { return; } if (0 < this.undecidedEnlistmentCount) { this.doomed = true; } else if (this.tooLateForEnlistments) { throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TransactionAlreadyOver"), null); } if (this.phase0EnlistVolatilementContainerList != null) { foreach (OletxPhase0VolatileEnlistmentContainer container in this.phase0EnlistVolatilementContainerList) { container.RollbackFromTransaction(); } } if (this.phase1EnlistVolatilementContainer != null) { this.phase1EnlistVolatilementContainer.RollbackFromTransaction(); } } try { this.transactionShim.Abort(); } catch (COMException exception) { if (System.Transactions.Oletx.NativeMethods.XACT_E_ALREADYINPROGRESS == exception.ErrorCode) { if (!this.doomed) { throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("TransactionAlreadyOver"), exception); } if (DiagnosticTrace.Verbose) { ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception); } } else { OletxTransactionManager.ProxyException(exception); throw; } } }
private static Oletx.OletxTransactionManager CheckTransactionManager(string nodeName) { Oletx.OletxTransactionManager tm = DistributedTransactionManager; if (!((tm.NodeName == null && (nodeName == null || nodeName.Length == 0)) || (tm.NodeName != null && tm.NodeName.Equals(nodeName)))) { throw new ArgumentException(SR.GetString(SR.InvalidRecoveryInformation), "recoveryInformation"); } return(tm); }
internal void TMDownFromInternalRM(OletxTransactionManager oletxTm) { lock (this) { if ((base.oletxTransaction == null) || (oletxTm == base.oletxTransaction.realOletxTransaction.OletxTransactionManagerInstance)) { this.tmWentDown = true; } } }
internal OletxResourceManager(OletxTransactionManager transactionManager, Guid resourceManagerIdentifier) { this.oletxTransactionManager = transactionManager; this.resourceManagerIdentifier = resourceManagerIdentifier; this.enlistmentHashtable = new Hashtable(); this.reenlistList = new ArrayList(); this.reenlistPendingList = new ArrayList(); this.reenlistThreadTimer = null; this.reenlistThread = null; this.recoveryCompleteCalledByApplication = false; }
internal bool CallProxyReenlistComplete() { bool flag = false; if (this.RecoveryCompleteCalledByApplication) { IResourceManagerShim resourceManagerShim = null; try { try { resourceManagerShim = this.ResourceManagerShim; if (resourceManagerShim != null) { resourceManagerShim.ReenlistComplete(); flag = true; } } catch (COMException exception) { if ((System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN == exception.ErrorCode) || (System.Transactions.Oletx.NativeMethods.XACT_E_TMNOTAVAILABLE == exception.ErrorCode)) { flag = false; if (DiagnosticTrace.Verbose) { ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception); } return(flag); } if (System.Transactions.Oletx.NativeMethods.XACT_E_RECOVERYALREADYDONE != exception.ErrorCode) { OletxTransactionManager.ProxyException(exception); throw; } return(true); } return(flag); } finally { resourceManagerShim = null; } } return(true); }
internal RealOletxTransaction(OletxTransactionManager transactionManager, ITransactionShim transactionShim, OutcomeEnlistment outcomeEnlistment, Guid identifier, OletxTransactionIsolationLevel oletxIsoLevel, bool isRoot) { bool flag = false; try { this.oletxTransactionManager = transactionManager; this.transactionShim = transactionShim; this.outcomeEnlistment = outcomeEnlistment; this.txGuid = identifier; this.isolationLevel = OletxTransactionManager.ConvertIsolationLevelFromProxyValue(oletxIsoLevel); this.status = TransactionStatus.Active; this.undisposedOletxTransactionCount = 0; this.phase0EnlistVolatilementContainerList = null; this.phase1EnlistVolatilementContainer = null; this.tooLateForEnlistments = false; this.internalTransaction = null; this.creationTime = DateTime.UtcNow; this.lastStateChangeTime = this.creationTime; this.internalClone = new OletxTransaction(this); if (this.outcomeEnlistment != null) { this.outcomeEnlistment.SetRealTransaction(this); } else { this.status = TransactionStatus.InDoubt; } if (DiagnosticTrace.HaveListeners) { DiagnosticTrace.TraceTransfer(this.txGuid); } flag = true; } finally { if (!flag && (this.outcomeEnlistment != null)) { this.outcomeEnlistment.UnregisterOutcomeCallback(); this.outcomeEnlistment = null; } } }
internal OletxResourceManager( OletxTransactionManager transactionManager, Guid resourceManagerIdentifier ) { Debug.Assert( null != transactionManager, "Argument is null" ); // This will get set later, after the resource manager is created with the proxy. this.resourceManagerShim = null; this.oletxTransactionManager = transactionManager; this.resourceManagerIdentifier = resourceManagerIdentifier; this.enlistmentHashtable = new Hashtable(); this.reenlistList = new ArrayList(); this.reenlistPendingList = new ArrayList(); reenlistThreadTimer = null; reenlistThread = null; recoveryCompleteCalledByApplication = false; }
internal void TMDownFromInternalRM(OletxTransactionManager oletxTM) { OletxEnlistment enlistment = null; IDictionaryEnumerator enumerator = null; Hashtable hashtable = null; this.ResourceManagerShim = null; lock (this.enlistmentHashtable.SyncRoot) { hashtable = (Hashtable)this.enlistmentHashtable.Clone(); } enumerator = hashtable.GetEnumerator(); while (enumerator.MoveNext()) { enlistment = enumerator.Value as OletxEnlistment; if (enlistment != null) { enlistment.TMDownFromInternalRM(oletxTM); } } }
internal OletxInternalResourceManager(OletxTransactionManager oletxTm) { this.oletxTm = oletxTm; this.myGuid = Guid.NewGuid(); }
internal void TMDownFromInternalRM( OletxTransactionManager oletxTm ) { lock ( this ) { // If we don't have an oletxTransaction or the passed oletxTm matches that of my oletxTransaction, the TM went down. if ( ( null == this.oletxTransaction ) || ( oletxTm == this.oletxTransaction.realOletxTransaction.OletxTransactionManagerInstance ) ) { this.tmWentDown = true; } } return; }
internal void TMDownFromInternalRM(OletxTransactionManager oletxTM) { OletxEnlistment enlistment = null; IDictionaryEnumerator enumerator = null; Hashtable hashtable = null; this.ResourceManagerShim = null; lock (this.enlistmentHashtable.SyncRoot) { hashtable = (Hashtable) this.enlistmentHashtable.Clone(); } enumerator = hashtable.GetEnumerator(); while (enumerator.MoveNext()) { enlistment = enumerator.Value as OletxEnlistment; if (enlistment != null) { enlistment.TMDownFromInternalRM(oletxTM); } } }
public bool PrepareRequest(bool singlePhase, byte[] prepareInfo) { IEnlistmentShim enlistmentShim = null; OletxEnlistmentState active = OletxEnlistmentState.Active; IEnlistmentNotificationInternal iEnlistmentNotification = null; OletxRecoveryInformation thingToConvert = null; lock (this) { if (this.state == OletxEnlistmentState.Active) { active = this.state = OletxEnlistmentState.Preparing; } else { active = this.state; } iEnlistmentNotification = this.iEnlistmentNotification; enlistmentShim = this.EnlistmentShim; base.oletxTransaction.realOletxTransaction.TooLateForEnlistments = true; } if (OletxEnlistmentState.Preparing == active) { thingToConvert = new OletxRecoveryInformation(prepareInfo); this.isSinglePhase = singlePhase; long length = prepareInfo.Length; this.proxyPrepareInfoByteArray = new byte[length]; Array.Copy(prepareInfo, this.proxyPrepareInfoByteArray, length); if (this.isSinglePhase && this.canDoSinglePhase) { ISinglePhaseNotificationInternal internal3 = (ISinglePhaseNotificationInternal)iEnlistmentNotification; this.state = OletxEnlistmentState.SinglePhaseCommitting; if (DiagnosticTrace.Verbose) { EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.SinglePhaseCommit); } internal3.SinglePhaseCommit(this); return(true); } byte[] resourceManagerRecoveryInformation = TransactionManager.ConvertToByteArray(thingToConvert); this.state = OletxEnlistmentState.Preparing; this.prepareInfoByteArray = TransactionManager.GetRecoveryInformation(base.oletxResourceManager.oletxTransactionManager.CreationNodeName, resourceManagerRecoveryInformation); if (DiagnosticTrace.Verbose) { EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Prepare); } iEnlistmentNotification.Prepare(this); return(false); } if (OletxEnlistmentState.Prepared == active) { try { enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.Prepared); return(false); } catch (COMException exception3) { OletxTransactionManager.ProxyException(exception3); throw; } } if (OletxEnlistmentState.Done == active) { try { bool flag; try { enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.ReadOnly); flag = true; } finally { this.FinishEnlistment(); } return(flag); } catch (COMException exception2) { OletxTransactionManager.ProxyException(exception2); throw; } } try { enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.Failed); } catch (COMException exception) { if (DiagnosticTrace.Verbose) { ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception); } } return(true); }
// Common constructor used by all types of constructors // Create a clean and fresh transaction. internal RealOletxTransaction(OletxTransactionManager transactionManager, ITransactionShim transactionShim, OutcomeEnlistment outcomeEnlistment, Guid identifier, OletxTransactionIsolationLevel oletxIsoLevel, bool isRoot ) { bool successful = false; try { // initialize the member fields this.oletxTransactionManager = transactionManager; this.transactionShim = transactionShim; this.outcomeEnlistment = outcomeEnlistment; this.txGuid = identifier; this.isolationLevel = OletxTransactionManager.ConvertIsolationLevelFromProxyValue( oletxIsoLevel ); this.status = TransactionStatus.Active; this.undisposedOletxTransactionCount = 0; this.phase0EnlistVolatilementContainerList = null; this.phase1EnlistVolatilementContainer = null; this.tooLateForEnlistments = false; this.internalTransaction = null; this.creationTime = DateTime.UtcNow; this.lastStateChangeTime = this.creationTime; // Connect this object with the OutcomeEnlistment. this.internalClone = new OletxTransaction( this ); // We have have been created without an outcome enlistment if it was too late to create // a clone from the ITransactionNative that we were created from. if ( null != this.outcomeEnlistment ) { this.outcomeEnlistment.SetRealTransaction( this ); } else { this.status = TransactionStatus.InDoubt; } if ( DiagnosticTrace.HaveListeners ) { DiagnosticTrace.TraceTransfer(this.txGuid); } successful = true; } finally { if (!successful) { if (this.outcomeEnlistment != null) { this.outcomeEnlistment.UnregisterOutcomeCallback(); this.outcomeEnlistment = null; } } } }
internal OletxVolatileEnlistmentContainer AddDependentClone(bool delayCommit) { IVoterBallotShim voterBallotShim = null; IPhase0EnlistmentShim shim2 = null; bool flag2 = false; bool flag = false; OletxVolatileEnlistmentContainer container3 = null; OletxPhase0VolatileEnlistmentContainer container = null; OletxPhase1VolatileEnlistmentContainer target = null; bool flag3 = false; bool flag5 = false; IntPtr zero = IntPtr.Zero; RuntimeHelpers.PrepareConstrainedRegions(); try { lock (this) { if (delayCommit) { if (this.phase0EnlistVolatilementContainerList == null) { this.phase0EnlistVolatilementContainerList = new ArrayList(1); } if (this.phase0EnlistVolatilementContainerList.Count == 0) { container = new OletxPhase0VolatileEnlistmentContainer(this); flag = true; } else { container = this.phase0EnlistVolatilementContainerList[this.phase0EnlistVolatilementContainerList.Count - 1] as OletxPhase0VolatileEnlistmentContainer; if (container != null) { this.TakeContainerLock(container, ref flag5); } if (!container.NewEnlistmentsAllowed) { this.ReleaseContainerLock(container, ref flag5); container = new OletxPhase0VolatileEnlistmentContainer(this); flag = true; } else { flag = false; } } if (flag) { zero = HandleTable.AllocHandle(container); } } else if (this.phase1EnlistVolatilementContainer == null) { target = new OletxPhase1VolatileEnlistmentContainer(this); flag2 = true; target.voterHandle = HandleTable.AllocHandle(target); } else { flag2 = false; target = this.phase1EnlistVolatilementContainer; } try { if (container != null) { this.TakeContainerLock(container, ref flag5); } if (flag) { this.transactionShim.Phase0Enlist(zero, out shim2); container.Phase0EnlistmentShim = shim2; } if (flag2) { this.OletxTransactionManagerInstance.dtcTransactionManagerLock.AcquireReaderLock(-1); try { this.transactionShim.CreateVoter(target.voterHandle, out voterBallotShim); flag3 = true; } finally { this.OletxTransactionManagerInstance.dtcTransactionManagerLock.ReleaseReaderLock(); } target.VoterBallotShim = voterBallotShim; } if (delayCommit) { if (flag) { this.phase0EnlistVolatilementContainerList.Add(container); } container.AddDependentClone(); return(container); } if (flag2) { this.phase1EnlistVolatilementContainer = target; } target.AddDependentClone(); return(target); } catch (COMException exception) { OletxTransactionManager.ProxyException(exception); throw; } return(container3); } } finally { if (container != null) { this.ReleaseContainerLock(container, ref flag5); } if ((zero != IntPtr.Zero) && (container.Phase0EnlistmentShim == null)) { HandleTable.FreeHandle(zero); } if ((!flag3 && (target != null)) && ((target.voterHandle != IntPtr.Zero) && flag2)) { HandleTable.FreeHandle(target.voterHandle); } } return(container3); }
internal OletxEnlistment EnlistDurable(OletxTransaction oletxTransaction, bool canDoSinglePhase, IEnlistmentNotificationInternal enlistmentNotification, EnlistmentOptions enlistmentOptions) { IResourceManagerShim resourceManagerShim = null; IPhase0EnlistmentShim shim2 = null; IEnlistmentShim enlistmentShim = null; IntPtr zero = IntPtr.Zero; bool flag3 = false; bool flag2 = false; OletxEnlistment target = new OletxEnlistment(canDoSinglePhase, enlistmentNotification, oletxTransaction.RealTransaction.TxGuid, enlistmentOptions, this, oletxTransaction); bool flag = false; RuntimeHelpers.PrepareConstrainedRegions(); try { if ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None) { RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { oletxTransaction.RealTransaction.IncrementUndecidedEnlistments(); flag2 = true; } } lock (target) { RuntimeHelpers.PrepareConstrainedRegions(); try { resourceManagerShim = this.ResourceManagerShim; if (resourceManagerShim == null) { throw TransactionManagerCommunicationException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), null); } if ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None) { zero = HandleTable.AllocHandle(target); RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { oletxTransaction.RealTransaction.TransactionShim.Phase0Enlist(zero, out shim2); flag3 = true; } target.Phase0EnlistmentShim = shim2; } target.phase1Handle = HandleTable.AllocHandle(target); resourceManagerShim.Enlist(oletxTransaction.RealTransaction.TransactionShim, target.phase1Handle, out enlistmentShim); target.EnlistmentShim = enlistmentShim; } catch (COMException exception) { if (System.Transactions.Oletx.NativeMethods.XACT_E_TOOMANY_ENLISTMENTS == exception.ErrorCode) { throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("OletxTooManyEnlistments"), exception); } OletxTransactionManager.ProxyException(exception); throw; } finally { if (target.EnlistmentShim == null) { if ((zero != IntPtr.Zero) && !flag3) { HandleTable.FreeHandle(zero); } if (target.phase1Handle != IntPtr.Zero) { HandleTable.FreeHandle(target.phase1Handle); } } } } flag = true; } finally { if ((!flag && ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None)) && flag2) { oletxTransaction.RealTransaction.DecrementUndecidedEnlistments(); } } return(target); }
void Initialize() { if (this.initialized) { return; } OletxInternalResourceManager internalRM = this.oletxTm.internalResourceManager; IntPtr handle = IntPtr.Zero; IResourceManagerShim resourceManagerShim = null; bool nodeNameMatches = false; CoTaskMemHandle whereaboutsBuffer = null; RuntimeHelpers.PrepareConstrainedRegions(); try { handle = HandleTable.AllocHandle(internalRM); this.proxyShimFactory.ConnectToProxy( this.nodeName, internalRM.Identifier, handle, out nodeNameMatches, out this.whereaboutsSize, out whereaboutsBuffer, out resourceManagerShim ); // If the node name does not match, throw. if (!nodeNameMatches) { throw new NotSupportedException(SR.GetString(SR.ProxyCannotSupportMultipleNodeNames)); } // Make a managed copy of the whereabouts. if ((null != whereaboutsBuffer) && (0 != this.whereaboutsSize)) { this.whereabouts = new byte[this.whereaboutsSize]; Marshal.Copy(whereaboutsBuffer.DangerousGetHandle(), this.whereabouts, 0, Convert.ToInt32(this.whereaboutsSize)); } // Give the IResourceManagerShim to the internalRM and tell it to call ReenlistComplete. internalRM.resourceManagerShim = resourceManagerShim; internalRM.CallReenlistComplete(); this.initialized = true; } catch (COMException ex) { if (NativeMethods.XACT_E_NOTSUPPORTED == ex.ErrorCode) { throw new NotSupportedException(SR.GetString(SR.CannotSupportNodeNameSpecification)); } OletxTransactionManager.ProxyException(ex); // Unfortunately MSDTCPRX may return unknown error codes when attempting to connect to MSDTC // that error should be propagated back as a TransactionManagerCommunicationException. throw TransactionManagerCommunicationException.Create( SR.GetString(SR.TraceSourceOletx), SR.GetString(SR.TransactionManagerCommunicationException), ex ); } finally { if (null != whereaboutsBuffer) { whereaboutsBuffer.Close(); } // If we weren't successful at initializing ourself, clear things out // for next time around. if (!this.initialized) { if (handle != IntPtr.Zero && null == resourceManagerShim) { HandleTable.FreeHandle(handle); } if (null != this.whereabouts) { this.whereabouts = null; this.whereaboutsSize = 0; } } } }
internal IPromotedEnlistment CommonEnlistVolatile(IEnlistmentNotificationInternal enlistmentNotification, EnlistmentOptions enlistmentOptions, OletxTransaction oletxTransaction) { OletxVolatileEnlistment enlistment = null; bool flag2 = false; bool flag = false; OletxPhase0VolatileEnlistmentContainer target = null; OletxPhase1VolatileEnlistmentContainer container = null; IntPtr zero = IntPtr.Zero; IVoterBallotShim voterBallotShim = null; IPhase0EnlistmentShim shim = null; bool flag3 = false; RuntimeHelpers.PrepareConstrainedRegions(); try { lock (this) { enlistment = new OletxVolatileEnlistment(enlistmentNotification, enlistmentOptions, oletxTransaction); if ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None) { if (this.phase0EnlistVolatilementContainerList == null) { this.phase0EnlistVolatilementContainerList = new ArrayList(1); } if (this.phase0EnlistVolatilementContainerList.Count == 0) { target = new OletxPhase0VolatileEnlistmentContainer(this); flag = true; } else { target = this.phase0EnlistVolatilementContainerList[this.phase0EnlistVolatilementContainerList.Count - 1] as OletxPhase0VolatileEnlistmentContainer; if (!target.NewEnlistmentsAllowed) { target = new OletxPhase0VolatileEnlistmentContainer(this); flag = true; } else { flag = false; } } if (flag) { zero = HandleTable.AllocHandle(target); } } else if (this.phase1EnlistVolatilementContainer == null) { flag2 = true; container = new OletxPhase1VolatileEnlistmentContainer(this) { voterHandle = HandleTable.AllocHandle(container) }; } else { flag2 = false; container = this.phase1EnlistVolatilementContainer; } try { if (flag) { lock (target) { this.transactionShim.Phase0Enlist(zero, out shim); target.Phase0EnlistmentShim = shim; } } if (flag2) { this.transactionShim.CreateVoter(container.voterHandle, out voterBallotShim); flag3 = true; container.VoterBallotShim = voterBallotShim; } if ((enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != EnlistmentOptions.None) { target.AddEnlistment(enlistment); if (flag) { this.phase0EnlistVolatilementContainerList.Add(target); } return(enlistment); } container.AddEnlistment(enlistment); if (flag2) { this.phase1EnlistVolatilementContainer = container; } return(enlistment); } catch (COMException exception) { OletxTransactionManager.ProxyException(exception); throw; } return(enlistment); } } finally { if ((zero != IntPtr.Zero) && (target.Phase0EnlistmentShim == null)) { HandleTable.FreeHandle(zero); } if ((!flag3 && (container != null)) && ((container.voterHandle != IntPtr.Zero) && flag2)) { HandleTable.FreeHandle(container.voterHandle); } } return(enlistment); }
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); }
// This is called by the internal RM when it gets a TM Down notification. This routine will // tell the enlistments about the TMDown from the internal RM. The enlistments will then // decide what to do, based on their state. This is mainly to work around COMPlus bug 36760/36758, // where Phase0 enlistments get Phase0Request( abortHint = false ) when the TM goes down. We want // to try to avoid telling the application to prepare when we know the transaction will abort. // We can't do this out of the normal TMDown notification to the RM because it is too late. The // Phase0Request gets sent before the TMDown notification. internal void TMDownFromInternalRM( OletxTransactionManager oletxTM ) { Hashtable localEnlistmentHashtable = null; IDictionaryEnumerator enlistEnum = null; OletxEnlistment enlistment = null; // If the internal RM got a TMDown, we will shortly, so null out our ResourceManagerShim now. this.ResourceManagerShim = null; // Make our own copy of the hashtable of enlistments. lock ( enlistmentHashtable.SyncRoot ) { localEnlistmentHashtable = (Hashtable) this.enlistmentHashtable.Clone(); } // Tell all of our enlistments that the TM went down. The proxy only // tells enlistments that are in the Prepared state, but we want our Phase0 // enlistments to know so they can avoid sending Prepare when they get a // Phase0Request - COMPlus bug 36760/36758. enlistEnum = localEnlistmentHashtable.GetEnumerator(); while ( enlistEnum.MoveNext() ) { enlistment = enlistEnum.Value as OletxEnlistment; if ( null != enlistment ) { enlistment.TMDownFromInternalRM( oletxTM ); } } }
static public Enlistment Reenlist( Guid resourceManagerIdentifier, byte[] recoveryInformation, IEnlistmentNotification enlistmentNotification ) { if (resourceManagerIdentifier == Guid.Empty) { throw new ArgumentException(SR.GetString(SR.BadResourceManagerId), "resourceManagerIdentifier"); } if (null == recoveryInformation) { throw new ArgumentNullException("recoveryInformation"); } if (null == enlistmentNotification) { throw new ArgumentNullException("enlistmentNotification"); } if (!TransactionManager._platformValidated) { TransactionManager.ValidatePlatform(); } if (DiagnosticTrace.Verbose) { MethodEnteredTraceRecord.Trace(SR.GetString(SR.TraceSourceBase), "TransactionManager.Reenlist" ); } if (DiagnosticTrace.Information) { ReenlistTraceRecord.Trace(SR.GetString(SR.TraceSourceBase), resourceManagerIdentifier ); } // Put the recovery information into a stream. MemoryStream stream = new MemoryStream(recoveryInformation); int recoveryInformationVersion = 0; string nodeName = null; byte[] resourceManagerRecoveryInformation = null; try { BinaryReader reader = new BinaryReader(stream); recoveryInformationVersion = reader.ReadInt32(); if (recoveryInformationVersion == TransactionManager.recoveryInformationVersion1) { nodeName = reader.ReadString(); resourceManagerRecoveryInformation = reader.ReadBytes(recoveryInformation.Length - checked ((int)stream.Position)); } else { if (DiagnosticTrace.Error) { TransactionExceptionTraceRecord.Trace(SR.GetString(SR.TraceSourceBase), SR.GetString(SR.UnrecognizedRecoveryInformation) ); } throw new ArgumentException(SR.GetString(SR.UnrecognizedRecoveryInformation), "recoveryInformation"); } } catch (System.IO.EndOfStreamException e) { if (DiagnosticTrace.Error) { TransactionExceptionTraceRecord.Trace(SR.GetString(SR.TraceSourceBase), SR.GetString(SR.UnrecognizedRecoveryInformation) ); } throw new ArgumentException(SR.GetString(SR.UnrecognizedRecoveryInformation), "recoveryInformation", e); } catch (System.FormatException e) { if (DiagnosticTrace.Error) { TransactionExceptionTraceRecord.Trace(SR.GetString(SR.TraceSourceBase), SR.GetString(SR.UnrecognizedRecoveryInformation) ); } throw new ArgumentException(SR.GetString(SR.UnrecognizedRecoveryInformation), "recoveryInformation", e); } finally { stream.Close(); } Oletx.OletxTransactionManager transactionManager = CheckTransactionManager(nodeName); // Now ask the Transaction Manager to reenlist. object syncRoot = new object(); Enlistment returnValue = new Enlistment(enlistmentNotification, syncRoot); EnlistmentState._EnlistmentStatePromoted.EnterState(returnValue.InternalEnlistment); returnValue.InternalEnlistment.PromotedEnlistment = transactionManager.ReenlistTransaction( resourceManagerIdentifier, resourceManagerRecoveryInformation, (RecoveringInternalEnlistment)returnValue.InternalEnlistment ); if (DiagnosticTrace.Verbose) { MethodExitedTraceRecord.Trace(SR.GetString(SR.TraceSourceBase), "TransactionManager.Reenlist" ); } return(returnValue); }