public void InDoubt(Exception e) { IEnlistmentShim localEnlistmentShim = null; if ( DiagnosticTrace.Verbose ) { MethodEnteredTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), "OletxSinglePhaseEnlistment.InDoubt" ); } if ( DiagnosticTrace.Warning ) { EnlistmentCallbackNegativeTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), this.InternalTraceIdentifier, EnlistmentCallback.InDoubt ); } lock ( this ) { if (!isSinglePhase || (OletxEnlistmentState.SinglePhaseCommitting != state)) { throw TransactionException.CreateEnlistmentStateException( SR.GetString( SR.TraceSourceOletx ), null ); } state = OletxEnlistmentState.InDoubt; localEnlistmentShim = this.EnlistmentShim; } lock ( this.oletxTransaction.realOletxTransaction ) { if ( this.oletxTransaction.realOletxTransaction.innerException == null ) { this.oletxTransaction.realOletxTransaction.innerException = e; } } try { if ( null != localEnlistmentShim ) { localEnlistmentShim.PrepareRequestDone( OletxPrepareVoteType.InDoubt ); } } catch ( COMException ex ) { // If the TM went down during our call, there is nothing special we have to do because // the App doesn't expect any more notifications. if ( ( NativeMethods.XACT_E_CONNECTION_DOWN == ex.ErrorCode ) || ( NativeMethods.XACT_E_TMNOTAVAILABLE == ex.ErrorCode ) ) { if ( DiagnosticTrace.Verbose ) { ExceptionConsumedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), ex ); } } else { throw; } } finally { FinishEnlistment(); } if ( DiagnosticTrace.Verbose ) { MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), "OletxSinglePhaseEnlistment.InDoubt" ); } }
internal OletxEnlistment( IEnlistmentNotificationInternal enlistmentNotification, OletxTransactionStatus xactStatus, byte[] prepareInfoByteArray, OletxResourceManager oletxResourceManager ) : base( oletxResourceManager, null ) { Guid myGuid = Guid.Empty; // This will get set later by the creator of this object after it // has enlisted with the proxy. this.enlistmentShim = null; this.phase0Shim = null; this.canDoSinglePhase = false; this.iEnlistmentNotification = enlistmentNotification; this.state = OletxEnlistmentState.Active; // Do this before we do any tracing because it will affect the trace identifiers that we generate. Debug.Assert( ( null != prepareInfoByteArray ), "OletxEnlistment.ctor - null oletxTransaction without a prepareInfoByteArray" ); int prepareInfoLength = prepareInfoByteArray.Length; this.proxyPrepareInfoByteArray = new byte[prepareInfoLength]; Array.Copy(prepareInfoByteArray, proxyPrepareInfoByteArray, prepareInfoLength); byte[] txGuidByteArray = new byte[16]; Array.Copy(proxyPrepareInfoByteArray, txGuidByteArray, 16); this.transactionGuid = new Guid( txGuidByteArray ); this.transactionGuidString = this.transactionGuid.ToString(); // If this is being created as part of a Reenlist and we already know the // outcome, then tell the application. switch (xactStatus) { case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_ABORTED: { this.state = OletxEnlistmentState.Aborting; if ( DiagnosticTrace.Verbose ) { EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), this.InternalTraceIdentifier, NotificationCall.Rollback ); } iEnlistmentNotification.Rollback( this ); break; } case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_COMMITTED: { this.state = OletxEnlistmentState.Committing; // We are going to send the notification to the RM. We need to put the // enlistment on the reenlistPendingList. We lock the reenlistList because // we have decided that is the lock that protects both lists. The entry will // be taken off the reenlistPendingList when the enlistment has // EnlistmentDone called on it. The enlistment will call // RemoveFromReenlistPending. lock ( oletxResourceManager.reenlistList ) { oletxResourceManager.reenlistPendingList.Add( this ); } if ( DiagnosticTrace.Verbose ) { EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), this.InternalTraceIdentifier, NotificationCall.Commit ); } iEnlistmentNotification.Commit( this ); break; } case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED: { this.state = OletxEnlistmentState.Prepared; lock ( oletxResourceManager.reenlistList ) { oletxResourceManager.reenlistList.Add( this ); oletxResourceManager.StartReenlistThread(); } break; } default: { if ( DiagnosticTrace.Critical ) { InternalErrorTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), SR.GetString( SR.OletxEnlistmentUnexpectedTransactionStatus ) ); } throw TransactionException.Create( SR.GetString( SR.TraceSourceOletx ), SR.GetString( SR.OletxEnlistmentUnexpectedTransactionStatus ), null ); } } if ( DiagnosticTrace.Information ) { EnlistmentTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), this.InternalTraceIdentifier, EnlistmentType.Durable, EnlistmentOptions.None ); } // Always do this last in case anything prior to this fails. AddToEnlistmentTable(); }
public void Committed() { IEnlistmentShim localEnlistmentShim = null; if ( DiagnosticTrace.Verbose ) { MethodEnteredTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), "OletxSinglePhaseEnlistment.Committed" ); EnlistmentCallbackPositiveTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), this.InternalTraceIdentifier, EnlistmentCallback.Committed ); } lock ( this ) { if (!isSinglePhase || (OletxEnlistmentState.SinglePhaseCommitting != state)) { throw TransactionException.CreateEnlistmentStateException( SR.GetString( SR.TraceSourceOletx ), null ); } state = OletxEnlistmentState.Committed; localEnlistmentShim = this.EnlistmentShim; } try { // This may be the result of a reenlist, which means we don't have a // reference to the proxy. if ( null != localEnlistmentShim ) { localEnlistmentShim.PrepareRequestDone( OletxPrepareVoteType.SinglePhase ); } } catch ( COMException ex ) { // If the TM went down during our call, there is nothing special we have to do because // the App doesn't expect any more notifications. if ( ( NativeMethods.XACT_E_CONNECTION_DOWN == ex.ErrorCode ) || ( NativeMethods.XACT_E_TMNOTAVAILABLE == ex.ErrorCode ) ) { if ( DiagnosticTrace.Verbose ) { ExceptionConsumedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), ex ); } } else { throw; } } finally { FinishEnlistment(); } if ( DiagnosticTrace.Verbose ) { MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), "OletxSinglePhaseEnlistment.Committed" ); } }
internal OletxEnlistment(IEnlistmentNotificationInternal enlistmentNotification, OletxTransactionStatus xactStatus, byte[] prepareInfoByteArray, OletxResourceManager oletxResourceManager) : base(oletxResourceManager, null) { this.transactionGuid = Guid.Empty; this.phase1Handle = IntPtr.Zero; this.enlistmentShim = null; this.phase0Shim = null; this.canDoSinglePhase = false; this.iEnlistmentNotification = enlistmentNotification; this.state = OletxEnlistmentState.Active; int length = prepareInfoByteArray.Length; this.proxyPrepareInfoByteArray = new byte[length]; Array.Copy(prepareInfoByteArray, this.proxyPrepareInfoByteArray, length); byte[] destinationArray = new byte[0x10]; Array.Copy(this.proxyPrepareInfoByteArray, destinationArray, 0x10); this.transactionGuid = new Guid(destinationArray); base.transactionGuidString = this.transactionGuid.ToString(); switch (xactStatus) { case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_PREPARED: this.state = OletxEnlistmentState.Prepared; lock (oletxResourceManager.reenlistList) { oletxResourceManager.reenlistList.Add(this); oletxResourceManager.StartReenlistThread(); goto Label_01CD; } break; case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_ABORTED: this.state = OletxEnlistmentState.Aborting; if (DiagnosticTrace.Verbose) { EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Rollback); } this.iEnlistmentNotification.Rollback(this); goto Label_01CD; case OletxTransactionStatus.OLETX_TRANSACTION_STATUS_COMMITTED: this.state = OletxEnlistmentState.Committing; lock (oletxResourceManager.reenlistList) { oletxResourceManager.reenlistPendingList.Add(this); } if (DiagnosticTrace.Verbose) { EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Commit); } this.iEnlistmentNotification.Commit(this); goto Label_01CD; } if (DiagnosticTrace.Critical) { InternalErrorTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("OletxEnlistmentUnexpectedTransactionStatus")); } throw TransactionException.Create(System.Transactions.SR.GetString("TraceSourceOletx"), System.Transactions.SR.GetString("OletxEnlistmentUnexpectedTransactionStatus"), null); Label_01CD: if (DiagnosticTrace.Information) { EnlistmentTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentType.Durable, EnlistmentOptions.None); } base.AddToEnlistmentTable(); }
public void ForceRollback( Exception e ) { IEnlistmentShim localEnlistmentShim = null; IPhase0EnlistmentShim localPhase0Shim = null; if ( DiagnosticTrace.Verbose ) { MethodEnteredTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), "OletxPreparingEnlistment.ForceRollback" ); } if ( DiagnosticTrace.Warning ) { EnlistmentCallbackNegativeTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), this.InternalTraceIdentifier, EnlistmentCallback.ForceRollback ); } lock ( this ) { if ( OletxEnlistmentState.Preparing == state ) { localEnlistmentShim = this.EnlistmentShim; } else if ( OletxEnlistmentState.Phase0Preparing == state ) { localPhase0Shim = this.Phase0EnlistmentShim; if ( null != localPhase0Shim ) { // We have a vote - decrement the undecided enlistment count. We only do this // if we are Phase0 enlistment. oletxTransaction.realOletxTransaction.DecrementUndecidedEnlistments(); } } else { throw TransactionException.CreateEnlistmentStateException( SR.GetString( SR.TraceSourceOletx ), null ); } state = OletxEnlistmentState.Aborted; } Interlocked.CompareExchange<Exception>( ref this.oletxTransaction.realOletxTransaction.innerException, e, null ); try { if ( null != localEnlistmentShim ) { try { localEnlistmentShim.PrepareRequestDone( OletxPrepareVoteType.Failed ); } finally { HandleTable.FreeHandle( this.phase1Handle ); } } if ( null != localPhase0Shim ) { localPhase0Shim.Phase0Done( false ); } // else // The TM must have gone down, thus causing our interface pointer to be // invalidated. The App doesn't expect any more notifications, so we can // just finish the enlistment. } catch ( COMException ex ) { // If the TM went down during our call, there is nothing special we have to do because // the App doesn't expect any more notifications. if ( ( NativeMethods.XACT_E_CONNECTION_DOWN == ex.ErrorCode ) || ( NativeMethods.XACT_E_TMNOTAVAILABLE == ex.ErrorCode ) ) { if ( DiagnosticTrace.Verbose ) { ExceptionConsumedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), ex ); } } else { throw; } } finally { FinishEnlistment(); } if ( DiagnosticTrace.Verbose ) { MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), "OletxPreparingEnlistment.ForceRollback" ); } }
// ITransactionPhase0NotifyAsync public void Phase0Request( bool abortingHint ) { IEnlistmentNotificationInternal localEnlistmentNotification = null; OletxEnlistmentState localState = OletxEnlistmentState.Active; OletxCommittableTransaction committableTx = null; bool commitNotYetCalled = false; if ( DiagnosticTrace.Verbose ) { MethodEnteredTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), "OletxEnlistment.Phase0Request" ); } committableTx = this.oletxTransaction.realOletxTransaction.committableTransaction; if ( null != committableTx ) { // We are dealing with the committable transaction. If Commit or BeginCommit has NOT been // called, then we are dealing with a situation where the TM went down and we are getting // a bogus Phase0Request with abortHint = false (COMPlus bug 36760/36758). This is an attempt // to not send the app a Prepare request when we know the transaction is going to abort. if (!committableTx.CommitCalled ) { commitNotYetCalled = true; } } lock ( this ) { this.aborting = abortingHint; // The app may have already called EnlistmentDone. If this occurs, don't bother sending // the notification to the app and we don't need to tell the proxy. if ( OletxEnlistmentState.Active == state ) { // If we got an abort hint or we are the committable transaction and Commit has not yet been called or the TM went down, // we don't want to do any more work on the transaction. The abort notifications will be sent by the phase 1 // enlistment if ( ( this.aborting ) || ( commitNotYetCalled ) || ( this.tmWentDown ) ) { // There is a possible ---- where we could get the Phase0Request before we are given the // shim. In that case, we will vote "no" when we are given the shim. if ( null != this.phase0Shim ) { try { this.phase0Shim.Phase0Done( false ); } // I am not going to check for XACT_E_PROTOCOL here because that check is a workaround for a bug // that only shows up if abortingHint is false. catch ( COMException ex ) { if ( DiagnosticTrace.Verbose ) { ExceptionConsumedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), ex ); } } } } else { localState = state = OletxEnlistmentState.Phase0Preparing; localEnlistmentNotification = iEnlistmentNotification; } } } // Tell the application to do the work. if ( null != localEnlistmentNotification ) { if ( OletxEnlistmentState.Phase0Preparing == localState ) { byte[] txGuidArray = transactionGuid.ToByteArray(); byte[] rmGuidArray = oletxResourceManager.resourceManagerIdentifier.ToByteArray(); byte[] temp = new byte[txGuidArray.Length + rmGuidArray.Length]; Thread.MemoryBarrier(); this.proxyPrepareInfoByteArray = temp; int index = 0; for ( index = 0; index < txGuidArray.Length; index++ ) { proxyPrepareInfoByteArray[index] = txGuidArray[index]; } for ( index = 0; index < rmGuidArray.Length; index++ ) { proxyPrepareInfoByteArray[txGuidArray.Length + index] = rmGuidArray[index]; } OletxRecoveryInformation oletxRecoveryInformation = new OletxRecoveryInformation( proxyPrepareInfoByteArray ); byte[] oletxRecoveryInformationByteArray = TransactionManager.ConvertToByteArray( oletxRecoveryInformation ); // this.prepareInfoByteArray = TransactionManager.GetRecoveryInformation( oletxResourceManager.oletxTransactionManager.CreationNodeName, oletxRecoveryInformationByteArray ); if ( DiagnosticTrace.Verbose ) { EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), this.InternalTraceIdentifier, NotificationCall.Prepare ); } localEnlistmentNotification.Prepare( this ); } else { // We must have had a ---- between EnlistmentDone and the proxy telling // us Phase0Request. Just return. if ( DiagnosticTrace.Verbose ) { MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), "OletxEnlistment.Phase0Request" ); } return; } } if ( DiagnosticTrace.Verbose ) { MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), "OletxEnlistment.Phase0Request" ); } }
internal OletxEnlistment( bool canDoSinglePhase, IEnlistmentNotificationInternal enlistmentNotification, Guid transactionGuid, EnlistmentOptions enlistmentOptions, OletxResourceManager oletxResourceManager, OletxTransaction oletxTransaction ) : base( oletxResourceManager, oletxTransaction ) { Guid myGuid = Guid.Empty; // This will get set later by the creator of this object after it // has enlisted with the proxy. this.enlistmentShim = null; this.phase0Shim = null; this.canDoSinglePhase = canDoSinglePhase; this.iEnlistmentNotification = enlistmentNotification; this.state = OletxEnlistmentState.Active; this.transactionGuid = transactionGuid; this.proxyPrepareInfoByteArray = null; if ( DiagnosticTrace.Information ) { EnlistmentTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), this.InternalTraceIdentifier, EnlistmentType.Durable, enlistmentOptions ); } // Always do this last incase anything earlier fails. AddToEnlistmentTable(); }
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; }
internal OletxEnlistment(bool canDoSinglePhase, IEnlistmentNotificationInternal enlistmentNotification, Guid transactionGuid, EnlistmentOptions enlistmentOptions, OletxResourceManager oletxResourceManager, OletxTransaction oletxTransaction) : base(oletxResourceManager, oletxTransaction) { this.transactionGuid = Guid.Empty; this.phase1Handle = IntPtr.Zero; this.enlistmentShim = null; this.phase0Shim = null; this.canDoSinglePhase = canDoSinglePhase; this.iEnlistmentNotification = enlistmentNotification; this.state = OletxEnlistmentState.Active; this.transactionGuid = transactionGuid; this.proxyPrepareInfoByteArray = null; if (DiagnosticTrace.Information) { EnlistmentTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentType.Durable, enlistmentOptions); } base.AddToEnlistmentTable(); }
public void Phase0Request(bool abortingHint) { IEnlistmentNotificationInternal iEnlistmentNotification = null; OletxEnlistmentState active = OletxEnlistmentState.Active; OletxCommittableTransaction committableTransaction = null; bool flag = false; if (DiagnosticTrace.Verbose) { MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxEnlistment.Phase0Request"); } committableTransaction = base.oletxTransaction.realOletxTransaction.committableTransaction; if ((committableTransaction != null) && !committableTransaction.CommitCalled) { flag = true; } lock (this) { this.aborting = abortingHint; if (this.state == OletxEnlistmentState.Active) { if ((this.aborting || flag) || this.tmWentDown) { if (this.phase0Shim != null) { try { this.phase0Shim.Phase0Done(false); } catch (COMException exception) { if (DiagnosticTrace.Verbose) { ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception); } } } } else { active = this.state = OletxEnlistmentState.Phase0Preparing; iEnlistmentNotification = this.iEnlistmentNotification; } } } if (iEnlistmentNotification != null) { if (OletxEnlistmentState.Phase0Preparing != active) { if (DiagnosticTrace.Verbose) { MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxEnlistment.Phase0Request"); } return; } byte[] buffer = this.transactionGuid.ToByteArray(); byte[] buffer2 = base.oletxResourceManager.resourceManagerIdentifier.ToByteArray(); byte[] buffer4 = new byte[buffer.Length + buffer2.Length]; Thread.MemoryBarrier(); this.proxyPrepareInfoByteArray = buffer4; int index = 0; for (index = 0; index < buffer.Length; index++) { this.proxyPrepareInfoByteArray[index] = buffer[index]; } for (index = 0; index < buffer2.Length; index++) { this.proxyPrepareInfoByteArray[buffer.Length + index] = buffer2[index]; } OletxRecoveryInformation thingToConvert = new OletxRecoveryInformation(this.proxyPrepareInfoByteArray); byte[] resourceManagerRecoveryInformation = TransactionManager.ConvertToByteArray(thingToConvert); 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); } if (DiagnosticTrace.Verbose) { MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxEnlistment.Phase0Request"); } }
public void Prepared() { int num1 = System.Transactions.Oletx.NativeMethods.S_OK; IEnlistmentShim enlistmentShim = null; IPhase0EnlistmentShim shim = null; bool fabricateRollback = false; if (DiagnosticTrace.Verbose) { MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxPreparingEnlistment.Prepared"); EnlistmentCallbackPositiveTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentCallback.Prepared); } lock (this) { if (OletxEnlistmentState.Preparing == this.state) { enlistmentShim = this.EnlistmentShim; } else { if (OletxEnlistmentState.Phase0Preparing != this.state) { throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null); } shim = this.Phase0EnlistmentShim; if (base.oletxTransaction.realOletxTransaction.Doomed || this.fabricateRollback) { this.fabricateRollback = true; fabricateRollback = this.fabricateRollback; } } this.state = OletxEnlistmentState.Prepared; } try { if (enlistmentShim != null) { enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.Prepared); } else if (shim != null) { base.oletxTransaction.realOletxTransaction.DecrementUndecidedEnlistments(); shim.Phase0Done(!fabricateRollback); } else { fabricateRollback = true; } if (fabricateRollback) { this.AbortRequest(); } } catch (COMException exception) { if ((System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN == exception.ErrorCode) || (System.Transactions.Oletx.NativeMethods.XACT_E_TMNOTAVAILABLE == exception.ErrorCode)) { if (DiagnosticTrace.Verbose) { ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception); } } else { if (System.Transactions.Oletx.NativeMethods.XACT_E_PROTOCOL != exception.ErrorCode) { throw; } this.Phase0EnlistmentShim = null; if (DiagnosticTrace.Verbose) { ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception); } } } if (DiagnosticTrace.Verbose) { MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxPreparingEnlistment.Prepared"); } }
public void InDoubt(Exception e) { IEnlistmentShim enlistmentShim = null; if (DiagnosticTrace.Verbose) { MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxSinglePhaseEnlistment.InDoubt"); } if (DiagnosticTrace.Warning) { EnlistmentCallbackNegativeTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentCallback.InDoubt); } lock (this) { if (!this.isSinglePhase || (OletxEnlistmentState.SinglePhaseCommitting != this.state)) { throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null); } this.state = OletxEnlistmentState.InDoubt; enlistmentShim = this.EnlistmentShim; } lock (base.oletxTransaction.realOletxTransaction) { if (base.oletxTransaction.realOletxTransaction.innerException == null) { base.oletxTransaction.realOletxTransaction.innerException = e; } } try { if (enlistmentShim != null) { enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.InDoubt); } } catch (COMException exception) { if ((System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN != exception.ErrorCode) && (System.Transactions.Oletx.NativeMethods.XACT_E_TMNOTAVAILABLE != exception.ErrorCode)) { throw; } if (DiagnosticTrace.Verbose) { ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception); } } finally { this.FinishEnlistment(); } if (DiagnosticTrace.Verbose) { MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxSinglePhaseEnlistment.InDoubt"); } }
public void ForceRollback(Exception e) { IPhase0EnlistmentShim shim = null; IEnlistmentShim enlistmentShim = null; if (DiagnosticTrace.Verbose) { MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxPreparingEnlistment.ForceRollback"); } if (DiagnosticTrace.Warning) { EnlistmentCallbackNegativeTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentCallback.ForceRollback); } lock (this) { if (OletxEnlistmentState.Preparing == this.state) { enlistmentShim = this.EnlistmentShim; } else { if (OletxEnlistmentState.Phase0Preparing != this.state) { throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null); } shim = this.Phase0EnlistmentShim; if (shim != null) { base.oletxTransaction.realOletxTransaction.DecrementUndecidedEnlistments(); } } this.state = OletxEnlistmentState.Aborted; } Interlocked.CompareExchange<Exception>(ref base.oletxTransaction.realOletxTransaction.innerException, e, null); try { if (enlistmentShim != null) { try { enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.Failed); } finally { HandleTable.FreeHandle(this.phase1Handle); } } if (shim != null) { shim.Phase0Done(false); } } catch (COMException exception) { if ((System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN != exception.ErrorCode) && (System.Transactions.Oletx.NativeMethods.XACT_E_TMNOTAVAILABLE != exception.ErrorCode)) { throw; } if (DiagnosticTrace.Verbose) { ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception); } } finally { this.FinishEnlistment(); } if (DiagnosticTrace.Verbose) { MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxPreparingEnlistment.ForceRollback"); } }
public void EnlistmentDone() { bool flag; if (DiagnosticTrace.Verbose) { MethodEnteredTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxEnlistment.EnlistmentDone"); EnlistmentCallbackPositiveTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, EnlistmentCallback.Done); } IEnlistmentShim enlistmentShim = null; IPhase0EnlistmentShim shim2 = null; OletxEnlistmentState active = OletxEnlistmentState.Active; bool fabricateRollback = false; lock (this) { active = this.state; if (this.state == OletxEnlistmentState.Active) { shim2 = this.Phase0EnlistmentShim; if (shim2 != null) { base.oletxTransaction.realOletxTransaction.DecrementUndecidedEnlistments(); } flag = false; } else if (OletxEnlistmentState.Preparing == this.state) { enlistmentShim = this.EnlistmentShim; flag = true; } else if (OletxEnlistmentState.Phase0Preparing == this.state) { shim2 = this.Phase0EnlistmentShim; base.oletxTransaction.realOletxTransaction.DecrementUndecidedEnlistments(); if (this.fabricateRollback) { flag = true; } else { flag = false; } } else { if (((OletxEnlistmentState.Committing != this.state) && (OletxEnlistmentState.Aborting != this.state)) && (OletxEnlistmentState.SinglePhaseCommitting != this.state)) { throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null); } enlistmentShim = this.EnlistmentShim; flag = true; } fabricateRollback = this.fabricateRollback; this.state = OletxEnlistmentState.Done; } try { if (enlistmentShim != null) { if (OletxEnlistmentState.Preparing == active) { try { enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.ReadOnly); goto Label_01C1; } finally { HandleTable.FreeHandle(this.phase1Handle); } } if (OletxEnlistmentState.Committing != active) { if (OletxEnlistmentState.Aborting != active) { if (OletxEnlistmentState.SinglePhaseCommitting != active) { throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null); } enlistmentShim.PrepareRequestDone(OletxPrepareVoteType.SinglePhase); } else if (!fabricateRollback) { enlistmentShim.AbortRequestDone(); } } else { enlistmentShim.CommitRequestDone(); } } else if (shim2 != null) { if (active != OletxEnlistmentState.Active) { if (OletxEnlistmentState.Phase0Preparing != active) { throw TransactionException.CreateEnlistmentStateException(System.Transactions.SR.GetString("TraceSourceOletx"), null); } shim2.Phase0Done(true); } else { shim2.Unenlist(); } } } catch (COMException exception) { flag = true; if (DiagnosticTrace.Verbose) { ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception); } } finally { if (flag) { this.FinishEnlistment(); } } Label_01C1: if (DiagnosticTrace.Verbose) { MethodExitedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), "OletxEnlistment.EnlistmentDone"); } }
// ITranactionResourceAsync.PrepareRequest public bool PrepareRequest( bool singlePhase, byte[] prepareInfo ) { IEnlistmentShim localEnlistmentShim = null; OletxEnlistmentState localState = OletxEnlistmentState.Active; IEnlistmentNotificationInternal localEnlistmentNotification = null; OletxRecoveryInformation oletxRecoveryInformation = null; bool enlistmentDone; lock ( this ) { if ( OletxEnlistmentState.Active == state ) { localState = state = OletxEnlistmentState.Preparing; } else { // We must have done the prepare work in Phase0, so just remember what state we are // in now. localState = state; } localEnlistmentNotification = iEnlistmentNotification; localEnlistmentShim = this.EnlistmentShim; this.oletxTransaction.realOletxTransaction.TooLateForEnlistments = true; } // If we went to Preparing state, send the app // a prepare request. if ( OletxEnlistmentState.Preparing == localState ) { oletxRecoveryInformation = new OletxRecoveryInformation( prepareInfo ); this.isSinglePhase = singlePhase; // Store the prepare info we are given. Debug.Assert(this.proxyPrepareInfoByteArray == null, "Unexpected value in this.proxyPrepareInfoByteArray"); long arrayLength = prepareInfo.Length; this.proxyPrepareInfoByteArray = new Byte[arrayLength]; Array.Copy(prepareInfo, this.proxyPrepareInfoByteArray, arrayLength); if ( this.isSinglePhase && this.canDoSinglePhase ) { ISinglePhaseNotificationInternal singlePhaseNotification = (ISinglePhaseNotificationInternal) localEnlistmentNotification; state = OletxEnlistmentState.SinglePhaseCommitting; // We don't call DecrementUndecidedEnlistments for Phase1 enlistments. if ( DiagnosticTrace.Verbose ) { EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), this.InternalTraceIdentifier, NotificationCall.SinglePhaseCommit ); } singlePhaseNotification.SinglePhaseCommit( this ); enlistmentDone = true; } else { // We need to turn the oletxRecoveryInformation into a byte array. byte[] oletxRecoveryInformationByteArray = TransactionManager.ConvertToByteArray( oletxRecoveryInformation ); state = OletxEnlistmentState.Preparing; // this.prepareInfoByteArray = TransactionManager.GetRecoveryInformation( oletxResourceManager.oletxTransactionManager.CreationNodeName, oletxRecoveryInformationByteArray ); if ( DiagnosticTrace.Verbose ) { EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), this.InternalTraceIdentifier, NotificationCall.Prepare ); } localEnlistmentNotification.Prepare( this ); enlistmentDone = false; } } else if ( OletxEnlistmentState.Prepared == localState ) { // We must have done our prepare work during Phase0 so just vote Yes. try { localEnlistmentShim.PrepareRequestDone( OletxPrepareVoteType.Prepared ); enlistmentDone = false; } catch ( COMException comException ) { OletxTransactionManager.ProxyException( comException ); throw; } } else if ( OletxEnlistmentState.Done == localState ) { try { // This was an early vote. Respond ReadOnly try { localEnlistmentShim.PrepareRequestDone( OletxPrepareVoteType.ReadOnly ); enlistmentDone = true; } finally { FinishEnlistment(); } } catch ( COMException comException ) { OletxTransactionManager.ProxyException( comException ); throw; } } else { // Any other state means we should vote NO to the proxy. try { localEnlistmentShim.PrepareRequestDone( OletxPrepareVoteType.Failed ); } catch ( COMException ex ) { // No point in rethrowing this. We are not on an app thread and we have already told // the app that the transaction is aborting. When the app calls EnlistmentDone, we will // do the final release of the ITransactionEnlistmentAsync. if ( DiagnosticTrace.Verbose ) { ExceptionConsumedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), ex ); } } enlistmentDone = true; } return enlistmentDone; }
public void AbortRequest() { IEnlistmentShim enlistmentShim = null; IEnlistmentNotificationInternal iEnlistmentNotification = null; bool flag = false; lock (this) { if ((this.state == OletxEnlistmentState.Active) || (OletxEnlistmentState.Prepared == this.state)) { this.state = OletxEnlistmentState.Aborting; iEnlistmentNotification = this.iEnlistmentNotification; } else { if (OletxEnlistmentState.Phase0Preparing == this.state) { this.fabricateRollback = true; } else { flag = true; } enlistmentShim = this.EnlistmentShim; } } if (iEnlistmentNotification != null) { if (DiagnosticTrace.Verbose) { EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Rollback); } iEnlistmentNotification.Rollback(this); } else if (enlistmentShim != null) { try { enlistmentShim.AbortRequestDone(); } catch (COMException exception) { if ((System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN != exception.ErrorCode) && (System.Transactions.Oletx.NativeMethods.XACT_E_TMNOTAVAILABLE != exception.ErrorCode)) { throw; } flag = true; if (DiagnosticTrace.Verbose) { ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception); } } finally { if (flag) { this.FinishEnlistment(); } } } }
public void AbortRequest() { OletxEnlistmentState localState = OletxEnlistmentState.Active; IEnlistmentNotificationInternal localEnlistmentNotification = null; IEnlistmentShim localEnlistmentShim = null; bool finishEnlistment = false; lock ( this ) { if ( ( OletxEnlistmentState.Active == state ) || ( OletxEnlistmentState.Prepared == state ) ) { localState = state = OletxEnlistmentState.Aborting; localEnlistmentNotification = iEnlistmentNotification; } else { // We must have received an EnlistmentDone already or we have // a notification outstanding (Phase0 prepare). localState = state; if ( OletxEnlistmentState.Phase0Preparing == state ) { this.fabricateRollback = true; } else { finishEnlistment = true; } localEnlistmentShim = this.EnlistmentShim; } } if ( null != localEnlistmentNotification ) { if ( DiagnosticTrace.Verbose ) { EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), this.InternalTraceIdentifier, NotificationCall.Rollback ); } localEnlistmentNotification.Rollback( this ); } else if ( null != localEnlistmentShim ) { // We need to respond to the proxy now. try { localEnlistmentShim.AbortRequestDone(); } catch ( COMException ex ) { // If the TM went down during our call, there is nothing special we have to do because // the App doesn't expect any more notifications. We do want to mark the enlistment // to finish, however. if ( ( NativeMethods.XACT_E_CONNECTION_DOWN == ex.ErrorCode ) || ( NativeMethods.XACT_E_TMNOTAVAILABLE == ex.ErrorCode ) ) { finishEnlistment = true; if ( DiagnosticTrace.Verbose ) { ExceptionConsumedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), ex ); } } else { throw; } } finally { if ( finishEnlistment ) { FinishEnlistment(); } } } return; }
public void EnlistmentDone() { if ( DiagnosticTrace.Verbose ) { MethodEnteredTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), "OletxEnlistment.EnlistmentDone" ); EnlistmentCallbackPositiveTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), this.InternalTraceIdentifier, EnlistmentCallback.Done ); } IEnlistmentShim localEnlistmentShim = null; IPhase0EnlistmentShim localPhase0Shim = null; OletxEnlistmentState localState = OletxEnlistmentState.Active; bool finishEnlistment; bool localFabricateRollback = false; lock ( this ) { localState = state; if ( OletxEnlistmentState.Active == state ) { // Early vote. If we are doing Phase0, we need to unenlist. Otherwise, just // remember. localPhase0Shim = this.Phase0EnlistmentShim; if ( null != localPhase0Shim ) { // We are a Phase0 enlistment and we have a vote - decrement the undecided enlistment count. // We only do this for Phase0 because we don't count Phase1 durable enlistments. oletxTransaction.realOletxTransaction.DecrementUndecidedEnlistments(); } finishEnlistment = false; } else if ( OletxEnlistmentState.Preparing == state ) { // Read only vote. Tell the proxy and go to the Done state. localEnlistmentShim = this.EnlistmentShim; // We don't decrement the undecided enlistment count for Preparing because we only count // Phase0 enlistments and we are in Phase1 in Preparing state. finishEnlistment = true; } else if ( OletxEnlistmentState.Phase0Preparing == state ) { // Read only vote to Phase0. Tell the proxy okay and go to the Done state. localPhase0Shim = this.Phase0EnlistmentShim; // We are a Phase0 enlistment and we have a vote - decrement the undecided enlistment count. // We only do this for Phase0 because we don't count Phase1 durable enlistments. oletxTransaction.realOletxTransaction.DecrementUndecidedEnlistments(); // If we would have fabricated a rollback then we have already received an abort request // from proxy and will not receive any more notifications. Otherwise more notifications // will be coming. if ( this.fabricateRollback ) { finishEnlistment = true; } else { finishEnlistment = false; } } else if ( ( OletxEnlistmentState.Committing == state ) || ( OletxEnlistmentState.Aborting == state ) || ( OletxEnlistmentState.SinglePhaseCommitting == state ) ) { localEnlistmentShim = this.EnlistmentShim; finishEnlistment = true; // We don't decrement the undecided enlistment count for SinglePhaseCommitting because we only // do it for Phase0 enlistments. } else { throw TransactionException.CreateEnlistmentStateException( SR.GetString( SR.TraceSourceOletx ), null ); } // If this.fabricateRollback is true, it means that we are fabricating this // AbortRequest, rather than having the proxy tell us. So we don't need // to respond to the proxy with AbortRequestDone. localFabricateRollback = this.fabricateRollback; state = OletxEnlistmentState.Done; } try { if ( null != localEnlistmentShim ) { if ( OletxEnlistmentState.Preparing == localState ) { try { localEnlistmentShim.PrepareRequestDone( OletxPrepareVoteType.ReadOnly ); } finally { HandleTable.FreeHandle( this.phase1Handle ); } } else if ( OletxEnlistmentState.Committing == localState ) { localEnlistmentShim.CommitRequestDone(); } else if ( OletxEnlistmentState.Aborting == localState ) { // If localFabricatRollback is true, it means that we are fabricating this // AbortRequest, rather than having the proxy tell us. So we don't need // to respond to the proxy with AbortRequestDone. if ( ! localFabricateRollback ) { localEnlistmentShim.AbortRequestDone(); } } else if ( OletxEnlistmentState.SinglePhaseCommitting == localState ) { localEnlistmentShim.PrepareRequestDone( OletxPrepareVoteType.SinglePhase ); } else { throw TransactionException.CreateEnlistmentStateException( SR.GetString( SR.TraceSourceOletx ), null ); } } else if ( null != localPhase0Shim ) { if ( OletxEnlistmentState.Active == localState ) { localPhase0Shim.Unenlist(); } else if ( OletxEnlistmentState.Phase0Preparing == localState ) { localPhase0Shim.Phase0Done( true ); } else { throw TransactionException.CreateEnlistmentStateException( SR.GetString( SR.TraceSourceOletx ), null ); } } } catch ( COMException ex ) { // If we get an error talking to the proxy, there is nothing special we have to do because // the App doesn't expect any more notifications. We do want to mark the enlistment // to finish, however. finishEnlistment = true; if ( DiagnosticTrace.Verbose ) { ExceptionConsumedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), ex ); } } finally { if ( finishEnlistment ) { FinishEnlistment(); } } if ( DiagnosticTrace.Verbose ) { MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), "OletxEnlistment.EnlistmentDone" ); } }
public void Prepared() { int hrResult = NativeMethods.S_OK; IEnlistmentShim localEnlistmentShim = null; IPhase0EnlistmentShim localPhase0Shim = null; bool localFabricateRollback = false; if ( DiagnosticTrace.Verbose ) { MethodEnteredTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), "OletxPreparingEnlistment.Prepared" ); EnlistmentCallbackPositiveTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), this.InternalTraceIdentifier, EnlistmentCallback.Prepared ); } lock ( this ) { if ( OletxEnlistmentState.Preparing == state ) { localEnlistmentShim = this.EnlistmentShim; } else if ( OletxEnlistmentState.Phase0Preparing == state ) { // If the transaction is doomed or we have fabricateRollback is true because the // transaction aborted while the Phase0 Prepare request was outstanding, // release the WrappedTransactionPhase0EnlistmentAsync and remember that // we have a pending rollback. localPhase0Shim = this.Phase0EnlistmentShim; if ( ( oletxTransaction.realOletxTransaction.Doomed ) || ( this.fabricateRollback ) ) { // Set fabricateRollback in case we got here because the transaction is doomed. this.fabricateRollback = true; localFabricateRollback = this.fabricateRollback; } } else { throw TransactionException.CreateEnlistmentStateException( SR.GetString( SR.TraceSourceOletx ), null ); } state = OletxEnlistmentState.Prepared; } try { if ( null != localEnlistmentShim ) { localEnlistmentShim.PrepareRequestDone( OletxPrepareVoteType.Prepared ); } else if ( null != localPhase0Shim ) { // We have a vote - decrement the undecided enlistment count. We do // this after checking Doomed because ForceRollback will decrement also. // We also do this only for Phase0 enlistments. oletxTransaction.realOletxTransaction.DecrementUndecidedEnlistments(); localPhase0Shim.Phase0Done( !localFabricateRollback ); } else // The TM must have gone down, thus causing our interface pointer to be // invalidated. So we need to drive abort of the enlistment as if we // received an AbortRequest. { localFabricateRollback = true; } if ( localFabricateRollback ) { AbortRequest(); } } catch ( COMException ex ) { // If the TM went down during our call, the TMDown notification to the enlistment // and RM will put this enlistment on the ReenlistList, if appropriate. The outcome // will be obtained by the ReenlistThread. if ( ( NativeMethods.XACT_E_CONNECTION_DOWN == ex.ErrorCode ) || ( NativeMethods.XACT_E_TMNOTAVAILABLE == ex.ErrorCode ) ) { if ( DiagnosticTrace.Verbose ) { ExceptionConsumedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), ex ); } } // In the case of Phase0, there is a bug in the proxy that causes an XACT_E_PROTOCOL // error if the TM goes down while the enlistment is still active. The Phase0Request is // sent out with abortHint false, but the state of the proxy object is not changed, causing // Phase0Done request to fail with XACT_E_PROTOCOL. // For Prepared, we want to make sure the proxy aborts the transaction. We don't need // to drive the abort to the application here because the Phase1 enlistment will do that. // In other words, treat this as if the proxy said Phase0Request( abortingHint = true ). else if ( NativeMethods.XACT_E_PROTOCOL == ex.ErrorCode ) { this.Phase0EnlistmentShim = null; if ( DiagnosticTrace.Verbose ) { ExceptionConsumedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), ex ); } } else { throw; } } if ( DiagnosticTrace.Verbose ) { MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ), "OletxPreparingEnlistment.Prepared" ); } }
public void CommitRequest() { IEnlistmentShim enlistmentShim = null; IEnlistmentNotificationInternal iEnlistmentNotification = null; bool flag = false; lock (this) { if (OletxEnlistmentState.Prepared == this.state) { this.state = OletxEnlistmentState.Committing; iEnlistmentNotification = this.iEnlistmentNotification; } else { enlistmentShim = this.EnlistmentShim; flag = true; } } if (iEnlistmentNotification != null) { if (DiagnosticTrace.Verbose) { EnlistmentNotificationCallTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), base.InternalTraceIdentifier, NotificationCall.Commit); } iEnlistmentNotification.Commit(this); } else if (enlistmentShim != null) { try { enlistmentShim.CommitRequestDone(); } catch (COMException exception) { if ((System.Transactions.Oletx.NativeMethods.XACT_E_CONNECTION_DOWN != exception.ErrorCode) && (System.Transactions.Oletx.NativeMethods.XACT_E_TMNOTAVAILABLE != exception.ErrorCode)) { throw; } flag = true; if (DiagnosticTrace.Verbose) { ExceptionConsumedTraceRecord.Trace(System.Transactions.SR.GetString("TraceSourceOletx"), exception); } } finally { if (flag) { this.FinishEnlistment(); } } } }