Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / tx / System / Transactions / VolatileEnlistmentState.cs / 1305376 / VolatileEnlistmentState.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Transactions { using System; using System.Diagnostics; using System.Globalization; using System.Threading; using System.Transactions.Diagnostics; internal delegate void FinishVolatileDelegate( InternalEnlistment enlistment ); // Base class for all volatile enlistment states internal abstract class VolatileEnlistmentState : EnlistmentState { private static VolatileEnlistmentActive _volatileEnlistmentActive; private static VolatileEnlistmentPreparing _volatileEnlistmentPreparing; private static VolatileEnlistmentPrepared _volatileEnlistmentPrepared; private static VolatileEnlistmentSPC _volatileEnlistmentSPC; private static VolatileEnlistmentPreparingAborting _volatileEnlistmentPreparingAborting; private static VolatileEnlistmentAborting _volatileEnlistmentAborting; private static VolatileEnlistmentCommitting _volatileEnlistmentCommitting; private static VolatileEnlistmentInDoubt _volatileEnlistmentInDoubt; private static VolatileEnlistmentEnded _volatileEnlistmentEnded; private static VolatileEnlistmentDone _volatileEnlistmentDone; // Object for synchronizing access to the entire class( avoiding lock( typeof( ... )) ) private static object classSyncObject; internal static VolatileEnlistmentActive _VolatileEnlistmentActive { get { if (_volatileEnlistmentActive == null) { lock (ClassSyncObject) { if (_volatileEnlistmentActive == null) { VolatileEnlistmentActive temp = new VolatileEnlistmentActive(); Thread.MemoryBarrier(); _volatileEnlistmentActive = temp; } } } return _volatileEnlistmentActive; } } protected static VolatileEnlistmentPreparing _VolatileEnlistmentPreparing { get { if (_volatileEnlistmentPreparing == null) { lock (ClassSyncObject) { if (_volatileEnlistmentPreparing == null) { VolatileEnlistmentPreparing temp = new VolatileEnlistmentPreparing(); Thread.MemoryBarrier(); _volatileEnlistmentPreparing = temp; } } } return _volatileEnlistmentPreparing; } } protected static VolatileEnlistmentPrepared _VolatileEnlistmentPrepared { get { if (_volatileEnlistmentPrepared == null) { lock (ClassSyncObject) { if (_volatileEnlistmentPrepared == null) { VolatileEnlistmentPrepared temp = new VolatileEnlistmentPrepared(); Thread.MemoryBarrier(); _volatileEnlistmentPrepared = temp; } } } return _volatileEnlistmentPrepared; } } protected static VolatileEnlistmentSPC _VolatileEnlistmentSPC { get { if (_volatileEnlistmentSPC == null) { lock (ClassSyncObject) { if (_volatileEnlistmentSPC == null) { VolatileEnlistmentSPC temp = new VolatileEnlistmentSPC(); Thread.MemoryBarrier(); _volatileEnlistmentSPC = temp; } } } return _volatileEnlistmentSPC; } } protected static VolatileEnlistmentPreparingAborting _VolatileEnlistmentPreparingAborting { get { if (_volatileEnlistmentPreparingAborting == null) { lock (ClassSyncObject) { if (_volatileEnlistmentPreparingAborting == null) { VolatileEnlistmentPreparingAborting temp = new VolatileEnlistmentPreparingAborting(); Thread.MemoryBarrier(); _volatileEnlistmentPreparingAborting = temp; } } } return _volatileEnlistmentPreparingAborting; } } protected static VolatileEnlistmentAborting _VolatileEnlistmentAborting { get { if (_volatileEnlistmentAborting == null) { lock (ClassSyncObject) { if (_volatileEnlistmentAborting == null) { VolatileEnlistmentAborting temp = new VolatileEnlistmentAborting(); Thread.MemoryBarrier(); _volatileEnlistmentAborting = temp; } } } return _volatileEnlistmentAborting; } } protected static VolatileEnlistmentCommitting _VolatileEnlistmentCommitting { get { if (_volatileEnlistmentCommitting == null) { lock (ClassSyncObject) { if (_volatileEnlistmentCommitting == null) { VolatileEnlistmentCommitting temp = new VolatileEnlistmentCommitting(); Thread.MemoryBarrier(); _volatileEnlistmentCommitting = temp; } } } return _volatileEnlistmentCommitting; } } protected static VolatileEnlistmentInDoubt _VolatileEnlistmentInDoubt { get { if (_volatileEnlistmentInDoubt == null) { lock (ClassSyncObject) { if (_volatileEnlistmentInDoubt == null) { VolatileEnlistmentInDoubt temp = new VolatileEnlistmentInDoubt(); Thread.MemoryBarrier(); _volatileEnlistmentInDoubt = temp; } } } return _volatileEnlistmentInDoubt; } } protected static VolatileEnlistmentEnded _VolatileEnlistmentEnded { get { if (_volatileEnlistmentEnded == null) { lock (ClassSyncObject) { if (_volatileEnlistmentEnded == null) { VolatileEnlistmentEnded temp = new VolatileEnlistmentEnded(); Thread.MemoryBarrier(); _volatileEnlistmentEnded = temp; } } } return _volatileEnlistmentEnded; } } protected static VolatileEnlistmentDone _VolatileEnlistmentDone { get { if (_volatileEnlistmentDone == null) { lock (ClassSyncObject) { if (_volatileEnlistmentDone == null) { VolatileEnlistmentDone temp = new VolatileEnlistmentDone(); Thread.MemoryBarrier(); _volatileEnlistmentDone = temp; } } } return _volatileEnlistmentDone; } } // Helper object for static synchronization private static object ClassSyncObject { get { if( classSyncObject == null ) { object o = new object(); Interlocked.CompareExchange( ref classSyncObject, o, null ); } return classSyncObject; } } // Override of get_RecoveryInformation to be more specific with the exception string. internal override byte[] RecoveryInformation(InternalEnlistment enlistment) { throw TransactionException.CreateInvalidOperationException( SR.GetString( SR.TraceSourceLtm ), SR.GetString( SR.VolEnlistNoRecoveryInfo), null ); } } // Active state for a volatile enlistment indicates that the enlistment has been created // but no one has begun committing or aborting the transaction. From this state the enlistment // can abort the transaction or call read only to indicate that it does not want to // participate further in the transaction. internal class VolatileEnlistmentActive : VolatileEnlistmentState { internal override void EnterState( InternalEnlistment enlistment ) { // Set the enlistment state enlistment.State = this; // Yeah it's active. } #region IEnlistment Related Events internal override void EnlistmentDone( InternalEnlistment enlistment ) { // End this enlistment _VolatileEnlistmentDone.EnterState( enlistment ); // Note another enlistment finished. enlistment.FinishEnlistment(); } #endregion #region State Change Events internal override void ChangeStatePreparing( InternalEnlistment enlistment ) { _VolatileEnlistmentPreparing.EnterState( enlistment ); } internal override void ChangeStateSinglePhaseCommit( InternalEnlistment enlistment ) { _VolatileEnlistmentSPC.EnterState( enlistment ); } #endregion #region Internal Events internal override void InternalAborted(InternalEnlistment enlistment) { // Change the enlistment state to aborting. _VolatileEnlistmentAborting.EnterState( enlistment ); } #endregion } // Preparing state is the time after prepare has been called but no response has been received. internal class VolatileEnlistmentPreparing : VolatileEnlistmentState { internal override void EnterState( InternalEnlistment enlistment ) { // Set the enlistment state enlistment.State = this; Monitor.Exit( enlistment.Transaction ); try // Don't hold this lock while calling into the application code. { if ( DiagnosticTrace.Verbose ) { EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ), enlistment.EnlistmentTraceId, NotificationCall.Prepare ); } enlistment.EnlistmentNotification.Prepare( enlistment.PreparingEnlistment ); } finally { #pragma warning disable 0618 //@ Monitor.Enter(enlistment.Transaction); #pragma warning restore 0618 } } internal override void EnlistmentDone( InternalEnlistment enlistment ) { _VolatileEnlistmentDone.EnterState( enlistment ); // Process Finished InternalEnlistment enlistment.FinishEnlistment(); } internal override void Prepared( InternalEnlistment enlistment ) { // Change the enlistments state to prepared. _VolatileEnlistmentPrepared.EnterState( enlistment ); // Process Finished InternalEnlistment enlistment.FinishEnlistment(); } // The enlistment says to abort start the abort sequence. internal override void ForceRollback( InternalEnlistment enlistment, Exception e ) { // Change enlistment state to aborting _VolatileEnlistmentEnded.EnterState( enlistment ); // Start the transaction aborting enlistment.Transaction.State.ChangeStateTransactionAborted( enlistment.Transaction, e ); // Process Finished InternalEnlistment enlistment.FinishEnlistment(); } internal override void ChangeStatePreparing( InternalEnlistment enlistment ) { // If the transaction promotes during phase 0 then the transition to // the promoted phase 0 state for the transaction may cause this // notification to be delivered again. So in this case it should be // ignored. } internal override void InternalAborted( InternalEnlistment enlistment ) { _VolatileEnlistmentPreparingAborting.EnterState( enlistment ); } } // SPC state for a volatile enlistment is the point at which there is exactly 1 enlisment // and it supports SPC. The TM will send a single phase commit to the enlistment and wait // for the response from the TM. internal class VolatileEnlistmentSPC : VolatileEnlistmentState { internal override void EnterState( InternalEnlistment enlistment ) { bool spcCommitted = false; // Set the enlistment state enlistment.State = this; // Send Single Phase Commit to the enlistment if ( DiagnosticTrace.Verbose ) { EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ), enlistment.EnlistmentTraceId, NotificationCall.SinglePhaseCommit ); } Monitor.Exit( enlistment.Transaction ); try // Don't hold this lock while calling into the application code. { enlistment.SinglePhaseNotification.SinglePhaseCommit( enlistment.SinglePhaseEnlistment ); spcCommitted = true; } finally { if (!spcCommitted) { //If we have an exception thrown in SPC, we don't know the if the enlistment is committed or not //reply indoubt enlistment.SinglePhaseEnlistment.InDoubt(); } #pragma warning disable 0618 //@ Monitor.Enter(enlistment.Transaction); #pragma warning restore 0618 } } internal override void EnlistmentDone( InternalEnlistment enlistment ) { _VolatileEnlistmentEnded.EnterState( enlistment ); enlistment.Transaction.State.ChangeStateTransactionCommitted( enlistment.Transaction ); } internal override void Committed( InternalEnlistment enlistment ) { _VolatileEnlistmentEnded.EnterState( enlistment ); enlistment.Transaction.State.ChangeStateTransactionCommitted( enlistment.Transaction ); } internal override void Aborted( InternalEnlistment enlistment, Exception e ) { _VolatileEnlistmentEnded.EnterState( enlistment ); enlistment.Transaction.State.ChangeStateTransactionAborted( enlistment.Transaction, e ); } internal override void InDoubt( InternalEnlistment enlistment, Exception e ) { _VolatileEnlistmentEnded.EnterState( enlistment ); if( enlistment.Transaction.innerException == null ) { enlistment.Transaction.innerException = e; } enlistment.Transaction.State.InDoubtFromEnlistment( enlistment.Transaction ); } } // Prepared state for a volatile enlistment is the point at which prepare has been called // and the enlistment has responded prepared. No enlistment operations are valid at this // point. The RM must wait for the TM to take the next action. internal class VolatileEnlistmentPrepared : VolatileEnlistmentState { internal override void EnterState( InternalEnlistment enlistment ) { // Set the enlistment state enlistment.State = this; // Wait for Committed } internal override void InternalAborted(InternalEnlistment enlistment) { _VolatileEnlistmentAborting.EnterState( enlistment ); } internal override void InternalCommitted( InternalEnlistment enlistment ) { _VolatileEnlistmentCommitting.EnterState( enlistment ); } internal override void InternalIndoubt( InternalEnlistment enlistment ) { // Change the enlistment state to InDoubt. _VolatileEnlistmentInDoubt.EnterState( enlistment ); } internal override void ChangeStatePreparing( InternalEnlistment enlistment ) { // This would happen in the second pass of a phase 0 wave. } } // Aborting state is when Rollback has been sent to the enlistment. internal class VolatileEnlistmentPreparingAborting : VolatileEnlistmentState { internal override void EnterState( InternalEnlistment enlistment ) { // Set the enlistment state enlistment.State = this; } internal override void EnlistmentDone( InternalEnlistment enlistment ) { // Move this enlistment to the ended state _VolatileEnlistmentEnded.EnterState( enlistment ); } internal override void Prepared( InternalEnlistment enlistment ) { // The enlistment has respondend so changes it's state to aborting. _VolatileEnlistmentAborting.EnterState( enlistment ); // Process Finished InternalEnlistment enlistment.FinishEnlistment(); } // The enlistment says to abort start the abort sequence. internal override void ForceRollback( InternalEnlistment enlistment, Exception e ) { // Change enlistment state to aborting _VolatileEnlistmentEnded.EnterState( enlistment ); // Record the exception in the transaction if( enlistment.Transaction.innerException == null ) { // Arguably this is the second call to ForceRollback and not the call that // aborted the transaction but just in case. enlistment.Transaction.innerException = e; } // Process Finished InternalEnlistment enlistment.FinishEnlistment(); } internal override void InternalAborted( InternalEnlistment enlistment ) { // If this event comes from multiple places just ignore it. Continue // waiting for the enlistment to respond so that we can respond to it. } } // Aborting state is when Rollback has been sent to the enlistment. internal class VolatileEnlistmentAborting : VolatileEnlistmentState { internal override void EnterState( InternalEnlistment enlistment ) { // Set the enlistment state enlistment.State = this; Monitor.Exit( enlistment.Transaction ); try // Don't hold this lock while calling into the application code. { if ( DiagnosticTrace.Verbose ) { EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ), enlistment.EnlistmentTraceId, NotificationCall.Rollback ); } enlistment.EnlistmentNotification.Rollback( enlistment.SinglePhaseEnlistment ); } finally { #pragma warning disable 0618 //@ Monitor.Enter(enlistment.Transaction); #pragma warning restore 0618 } } internal override void ChangeStatePreparing( InternalEnlistment enlistment ) { // This enlistment was told to abort before being told to prepare } internal override void EnlistmentDone( InternalEnlistment enlistment ) { // Move this enlistment to the ended state _VolatileEnlistmentEnded.EnterState( enlistment ); } internal override void InternalAborted( InternalEnlistment enlistment ) { // Already working on it. } } // Committing state is when Commit has been sent to the enlistment. internal class VolatileEnlistmentCommitting : VolatileEnlistmentState { internal override void EnterState( InternalEnlistment enlistment ) { // Set the enlistment state enlistment.State = this; Monitor.Exit( enlistment.Transaction ); try // Don't hold this lock while calling into the application code. { if ( DiagnosticTrace.Verbose ) { EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ), enlistment.EnlistmentTraceId, NotificationCall.Commit ); } // Forward the notification to the enlistment enlistment.EnlistmentNotification.Commit( enlistment.Enlistment ); } finally { #pragma warning disable 0618 //@ Monitor.Enter(enlistment.Transaction); #pragma warning restore 0618 } } internal override void EnlistmentDone( InternalEnlistment enlistment ) { // Move this enlistment to the ended state _VolatileEnlistmentEnded.EnterState( enlistment ); } } // InDoubt state is for an enlistment that has sent indoubt but has not been responeded to. internal class VolatileEnlistmentInDoubt : VolatileEnlistmentState { internal override void EnterState( InternalEnlistment enlistment ) { // Set the enlistment state enlistment.State = this; Monitor.Exit( enlistment.Transaction ); try // Don't hold this lock while calling into the application code. { if ( DiagnosticTrace.Verbose ) { EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ), enlistment.EnlistmentTraceId, NotificationCall.InDoubt ); } // Forward the notification to the enlistment enlistment.EnlistmentNotification.InDoubt( enlistment.PreparingEnlistment ); } finally { #pragma warning disable 0618 //@ Monitor.Enter(enlistment.Transaction); #pragma warning restore 0618 } } internal override void EnlistmentDone( InternalEnlistment enlistment ) { // Move this enlistment to the ended state _VolatileEnlistmentEnded.EnterState( enlistment ); } } // Ended state is the state that is entered when the transaction has committed, // aborted, or said read only for an enlistment. At this point there are no valid // operations on the enlistment. internal class VolatileEnlistmentEnded : VolatileEnlistmentState { internal override void EnterState( InternalEnlistment enlistment ) { // Set the enlistment state enlistment.State = this; // Nothing to do. } internal override void ChangeStatePreparing( InternalEnlistment enlistment ) { // This enlistment was told to abort before being told to prepare } internal override void InternalAborted( InternalEnlistment enlistment ) { // Ignore this in case the enlistment gets here before // the transaction tells it to do so } internal override void InternalCommitted( InternalEnlistment enlistment ) { // Ignore this in case the enlistment gets here before // the transaction tells it to do so } internal override void InternalIndoubt(InternalEnlistment enlistment) { // Ignore this in case the enlistment gets here before // the transaction tells it to do so } internal override void InDoubt(InternalEnlistment enlistment, Exception e) { // Ignore this in case the enlistment gets here before // the transaction tells it to do so } } // At some point either early or late the enlistment responded ReadOnly internal class VolatileEnlistmentDone : VolatileEnlistmentEnded { internal override void EnterState( InternalEnlistment enlistment ) { // Set the enlistment state enlistment.State = this; // Nothing to do. } internal override void ChangeStatePreparing( InternalEnlistment enlistment ) { enlistment.CheckComplete(); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Transactions { using System; using System.Diagnostics; using System.Globalization; using System.Threading; using System.Transactions.Diagnostics; internal delegate void FinishVolatileDelegate( InternalEnlistment enlistment ); // Base class for all volatile enlistment states internal abstract class VolatileEnlistmentState : EnlistmentState { private static VolatileEnlistmentActive _volatileEnlistmentActive; private static VolatileEnlistmentPreparing _volatileEnlistmentPreparing; private static VolatileEnlistmentPrepared _volatileEnlistmentPrepared; private static VolatileEnlistmentSPC _volatileEnlistmentSPC; private static VolatileEnlistmentPreparingAborting _volatileEnlistmentPreparingAborting; private static VolatileEnlistmentAborting _volatileEnlistmentAborting; private static VolatileEnlistmentCommitting _volatileEnlistmentCommitting; private static VolatileEnlistmentInDoubt _volatileEnlistmentInDoubt; private static VolatileEnlistmentEnded _volatileEnlistmentEnded; private static VolatileEnlistmentDone _volatileEnlistmentDone; // Object for synchronizing access to the entire class( avoiding lock( typeof( ... )) ) private static object classSyncObject; internal static VolatileEnlistmentActive _VolatileEnlistmentActive { get { if (_volatileEnlistmentActive == null) { lock (ClassSyncObject) { if (_volatileEnlistmentActive == null) { VolatileEnlistmentActive temp = new VolatileEnlistmentActive(); Thread.MemoryBarrier(); _volatileEnlistmentActive = temp; } } } return _volatileEnlistmentActive; } } protected static VolatileEnlistmentPreparing _VolatileEnlistmentPreparing { get { if (_volatileEnlistmentPreparing == null) { lock (ClassSyncObject) { if (_volatileEnlistmentPreparing == null) { VolatileEnlistmentPreparing temp = new VolatileEnlistmentPreparing(); Thread.MemoryBarrier(); _volatileEnlistmentPreparing = temp; } } } return _volatileEnlistmentPreparing; } } protected static VolatileEnlistmentPrepared _VolatileEnlistmentPrepared { get { if (_volatileEnlistmentPrepared == null) { lock (ClassSyncObject) { if (_volatileEnlistmentPrepared == null) { VolatileEnlistmentPrepared temp = new VolatileEnlistmentPrepared(); Thread.MemoryBarrier(); _volatileEnlistmentPrepared = temp; } } } return _volatileEnlistmentPrepared; } } protected static VolatileEnlistmentSPC _VolatileEnlistmentSPC { get { if (_volatileEnlistmentSPC == null) { lock (ClassSyncObject) { if (_volatileEnlistmentSPC == null) { VolatileEnlistmentSPC temp = new VolatileEnlistmentSPC(); Thread.MemoryBarrier(); _volatileEnlistmentSPC = temp; } } } return _volatileEnlistmentSPC; } } protected static VolatileEnlistmentPreparingAborting _VolatileEnlistmentPreparingAborting { get { if (_volatileEnlistmentPreparingAborting == null) { lock (ClassSyncObject) { if (_volatileEnlistmentPreparingAborting == null) { VolatileEnlistmentPreparingAborting temp = new VolatileEnlistmentPreparingAborting(); Thread.MemoryBarrier(); _volatileEnlistmentPreparingAborting = temp; } } } return _volatileEnlistmentPreparingAborting; } } protected static VolatileEnlistmentAborting _VolatileEnlistmentAborting { get { if (_volatileEnlistmentAborting == null) { lock (ClassSyncObject) { if (_volatileEnlistmentAborting == null) { VolatileEnlistmentAborting temp = new VolatileEnlistmentAborting(); Thread.MemoryBarrier(); _volatileEnlistmentAborting = temp; } } } return _volatileEnlistmentAborting; } } protected static VolatileEnlistmentCommitting _VolatileEnlistmentCommitting { get { if (_volatileEnlistmentCommitting == null) { lock (ClassSyncObject) { if (_volatileEnlistmentCommitting == null) { VolatileEnlistmentCommitting temp = new VolatileEnlistmentCommitting(); Thread.MemoryBarrier(); _volatileEnlistmentCommitting = temp; } } } return _volatileEnlistmentCommitting; } } protected static VolatileEnlistmentInDoubt _VolatileEnlistmentInDoubt { get { if (_volatileEnlistmentInDoubt == null) { lock (ClassSyncObject) { if (_volatileEnlistmentInDoubt == null) { VolatileEnlistmentInDoubt temp = new VolatileEnlistmentInDoubt(); Thread.MemoryBarrier(); _volatileEnlistmentInDoubt = temp; } } } return _volatileEnlistmentInDoubt; } } protected static VolatileEnlistmentEnded _VolatileEnlistmentEnded { get { if (_volatileEnlistmentEnded == null) { lock (ClassSyncObject) { if (_volatileEnlistmentEnded == null) { VolatileEnlistmentEnded temp = new VolatileEnlistmentEnded(); Thread.MemoryBarrier(); _volatileEnlistmentEnded = temp; } } } return _volatileEnlistmentEnded; } } protected static VolatileEnlistmentDone _VolatileEnlistmentDone { get { if (_volatileEnlistmentDone == null) { lock (ClassSyncObject) { if (_volatileEnlistmentDone == null) { VolatileEnlistmentDone temp = new VolatileEnlistmentDone(); Thread.MemoryBarrier(); _volatileEnlistmentDone = temp; } } } return _volatileEnlistmentDone; } } // Helper object for static synchronization private static object ClassSyncObject { get { if( classSyncObject == null ) { object o = new object(); Interlocked.CompareExchange( ref classSyncObject, o, null ); } return classSyncObject; } } // Override of get_RecoveryInformation to be more specific with the exception string. internal override byte[] RecoveryInformation(InternalEnlistment enlistment) { throw TransactionException.CreateInvalidOperationException( SR.GetString( SR.TraceSourceLtm ), SR.GetString( SR.VolEnlistNoRecoveryInfo), null ); } } // Active state for a volatile enlistment indicates that the enlistment has been created // but no one has begun committing or aborting the transaction. From this state the enlistment // can abort the transaction or call read only to indicate that it does not want to // participate further in the transaction. internal class VolatileEnlistmentActive : VolatileEnlistmentState { internal override void EnterState( InternalEnlistment enlistment ) { // Set the enlistment state enlistment.State = this; // Yeah it's active. } #region IEnlistment Related Events internal override void EnlistmentDone( InternalEnlistment enlistment ) { // End this enlistment _VolatileEnlistmentDone.EnterState( enlistment ); // Note another enlistment finished. enlistment.FinishEnlistment(); } #endregion #region State Change Events internal override void ChangeStatePreparing( InternalEnlistment enlistment ) { _VolatileEnlistmentPreparing.EnterState( enlistment ); } internal override void ChangeStateSinglePhaseCommit( InternalEnlistment enlistment ) { _VolatileEnlistmentSPC.EnterState( enlistment ); } #endregion #region Internal Events internal override void InternalAborted(InternalEnlistment enlistment) { // Change the enlistment state to aborting. _VolatileEnlistmentAborting.EnterState( enlistment ); } #endregion } // Preparing state is the time after prepare has been called but no response has been received. internal class VolatileEnlistmentPreparing : VolatileEnlistmentState { internal override void EnterState( InternalEnlistment enlistment ) { // Set the enlistment state enlistment.State = this; Monitor.Exit( enlistment.Transaction ); try // Don't hold this lock while calling into the application code. { if ( DiagnosticTrace.Verbose ) { EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ), enlistment.EnlistmentTraceId, NotificationCall.Prepare ); } enlistment.EnlistmentNotification.Prepare( enlistment.PreparingEnlistment ); } finally { #pragma warning disable 0618 //@ Monitor.Enter(enlistment.Transaction); #pragma warning restore 0618 } } internal override void EnlistmentDone( InternalEnlistment enlistment ) { _VolatileEnlistmentDone.EnterState( enlistment ); // Process Finished InternalEnlistment enlistment.FinishEnlistment(); } internal override void Prepared( InternalEnlistment enlistment ) { // Change the enlistments state to prepared. _VolatileEnlistmentPrepared.EnterState( enlistment ); // Process Finished InternalEnlistment enlistment.FinishEnlistment(); } // The enlistment says to abort start the abort sequence. internal override void ForceRollback( InternalEnlistment enlistment, Exception e ) { // Change enlistment state to aborting _VolatileEnlistmentEnded.EnterState( enlistment ); // Start the transaction aborting enlistment.Transaction.State.ChangeStateTransactionAborted( enlistment.Transaction, e ); // Process Finished InternalEnlistment enlistment.FinishEnlistment(); } internal override void ChangeStatePreparing( InternalEnlistment enlistment ) { // If the transaction promotes during phase 0 then the transition to // the promoted phase 0 state for the transaction may cause this // notification to be delivered again. So in this case it should be // ignored. } internal override void InternalAborted( InternalEnlistment enlistment ) { _VolatileEnlistmentPreparingAborting.EnterState( enlistment ); } } // SPC state for a volatile enlistment is the point at which there is exactly 1 enlisment // and it supports SPC. The TM will send a single phase commit to the enlistment and wait // for the response from the TM. internal class VolatileEnlistmentSPC : VolatileEnlistmentState { internal override void EnterState( InternalEnlistment enlistment ) { bool spcCommitted = false; // Set the enlistment state enlistment.State = this; // Send Single Phase Commit to the enlistment if ( DiagnosticTrace.Verbose ) { EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ), enlistment.EnlistmentTraceId, NotificationCall.SinglePhaseCommit ); } Monitor.Exit( enlistment.Transaction ); try // Don't hold this lock while calling into the application code. { enlistment.SinglePhaseNotification.SinglePhaseCommit( enlistment.SinglePhaseEnlistment ); spcCommitted = true; } finally { if (!spcCommitted) { //If we have an exception thrown in SPC, we don't know the if the enlistment is committed or not //reply indoubt enlistment.SinglePhaseEnlistment.InDoubt(); } #pragma warning disable 0618 //@ Monitor.Enter(enlistment.Transaction); #pragma warning restore 0618 } } internal override void EnlistmentDone( InternalEnlistment enlistment ) { _VolatileEnlistmentEnded.EnterState( enlistment ); enlistment.Transaction.State.ChangeStateTransactionCommitted( enlistment.Transaction ); } internal override void Committed( InternalEnlistment enlistment ) { _VolatileEnlistmentEnded.EnterState( enlistment ); enlistment.Transaction.State.ChangeStateTransactionCommitted( enlistment.Transaction ); } internal override void Aborted( InternalEnlistment enlistment, Exception e ) { _VolatileEnlistmentEnded.EnterState( enlistment ); enlistment.Transaction.State.ChangeStateTransactionAborted( enlistment.Transaction, e ); } internal override void InDoubt( InternalEnlistment enlistment, Exception e ) { _VolatileEnlistmentEnded.EnterState( enlistment ); if( enlistment.Transaction.innerException == null ) { enlistment.Transaction.innerException = e; } enlistment.Transaction.State.InDoubtFromEnlistment( enlistment.Transaction ); } } // Prepared state for a volatile enlistment is the point at which prepare has been called // and the enlistment has responded prepared. No enlistment operations are valid at this // point. The RM must wait for the TM to take the next action. internal class VolatileEnlistmentPrepared : VolatileEnlistmentState { internal override void EnterState( InternalEnlistment enlistment ) { // Set the enlistment state enlistment.State = this; // Wait for Committed } internal override void InternalAborted(InternalEnlistment enlistment) { _VolatileEnlistmentAborting.EnterState( enlistment ); } internal override void InternalCommitted( InternalEnlistment enlistment ) { _VolatileEnlistmentCommitting.EnterState( enlistment ); } internal override void InternalIndoubt( InternalEnlistment enlistment ) { // Change the enlistment state to InDoubt. _VolatileEnlistmentInDoubt.EnterState( enlistment ); } internal override void ChangeStatePreparing( InternalEnlistment enlistment ) { // This would happen in the second pass of a phase 0 wave. } } // Aborting state is when Rollback has been sent to the enlistment. internal class VolatileEnlistmentPreparingAborting : VolatileEnlistmentState { internal override void EnterState( InternalEnlistment enlistment ) { // Set the enlistment state enlistment.State = this; } internal override void EnlistmentDone( InternalEnlistment enlistment ) { // Move this enlistment to the ended state _VolatileEnlistmentEnded.EnterState( enlistment ); } internal override void Prepared( InternalEnlistment enlistment ) { // The enlistment has respondend so changes it's state to aborting. _VolatileEnlistmentAborting.EnterState( enlistment ); // Process Finished InternalEnlistment enlistment.FinishEnlistment(); } // The enlistment says to abort start the abort sequence. internal override void ForceRollback( InternalEnlistment enlistment, Exception e ) { // Change enlistment state to aborting _VolatileEnlistmentEnded.EnterState( enlistment ); // Record the exception in the transaction if( enlistment.Transaction.innerException == null ) { // Arguably this is the second call to ForceRollback and not the call that // aborted the transaction but just in case. enlistment.Transaction.innerException = e; } // Process Finished InternalEnlistment enlistment.FinishEnlistment(); } internal override void InternalAborted( InternalEnlistment enlistment ) { // If this event comes from multiple places just ignore it. Continue // waiting for the enlistment to respond so that we can respond to it. } } // Aborting state is when Rollback has been sent to the enlistment. internal class VolatileEnlistmentAborting : VolatileEnlistmentState { internal override void EnterState( InternalEnlistment enlistment ) { // Set the enlistment state enlistment.State = this; Monitor.Exit( enlistment.Transaction ); try // Don't hold this lock while calling into the application code. { if ( DiagnosticTrace.Verbose ) { EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ), enlistment.EnlistmentTraceId, NotificationCall.Rollback ); } enlistment.EnlistmentNotification.Rollback( enlistment.SinglePhaseEnlistment ); } finally { #pragma warning disable 0618 //@ Monitor.Enter(enlistment.Transaction); #pragma warning restore 0618 } } internal override void ChangeStatePreparing( InternalEnlistment enlistment ) { // This enlistment was told to abort before being told to prepare } internal override void EnlistmentDone( InternalEnlistment enlistment ) { // Move this enlistment to the ended state _VolatileEnlistmentEnded.EnterState( enlistment ); } internal override void InternalAborted( InternalEnlistment enlistment ) { // Already working on it. } } // Committing state is when Commit has been sent to the enlistment. internal class VolatileEnlistmentCommitting : VolatileEnlistmentState { internal override void EnterState( InternalEnlistment enlistment ) { // Set the enlistment state enlistment.State = this; Monitor.Exit( enlistment.Transaction ); try // Don't hold this lock while calling into the application code. { if ( DiagnosticTrace.Verbose ) { EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ), enlistment.EnlistmentTraceId, NotificationCall.Commit ); } // Forward the notification to the enlistment enlistment.EnlistmentNotification.Commit( enlistment.Enlistment ); } finally { #pragma warning disable 0618 //@ Monitor.Enter(enlistment.Transaction); #pragma warning restore 0618 } } internal override void EnlistmentDone( InternalEnlistment enlistment ) { // Move this enlistment to the ended state _VolatileEnlistmentEnded.EnterState( enlistment ); } } // InDoubt state is for an enlistment that has sent indoubt but has not been responeded to. internal class VolatileEnlistmentInDoubt : VolatileEnlistmentState { internal override void EnterState( InternalEnlistment enlistment ) { // Set the enlistment state enlistment.State = this; Monitor.Exit( enlistment.Transaction ); try // Don't hold this lock while calling into the application code. { if ( DiagnosticTrace.Verbose ) { EnlistmentNotificationCallTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ), enlistment.EnlistmentTraceId, NotificationCall.InDoubt ); } // Forward the notification to the enlistment enlistment.EnlistmentNotification.InDoubt( enlistment.PreparingEnlistment ); } finally { #pragma warning disable 0618 //@ Monitor.Enter(enlistment.Transaction); #pragma warning restore 0618 } } internal override void EnlistmentDone( InternalEnlistment enlistment ) { // Move this enlistment to the ended state _VolatileEnlistmentEnded.EnterState( enlistment ); } } // Ended state is the state that is entered when the transaction has committed, // aborted, or said read only for an enlistment. At this point there are no valid // operations on the enlistment. internal class VolatileEnlistmentEnded : VolatileEnlistmentState { internal override void EnterState( InternalEnlistment enlistment ) { // Set the enlistment state enlistment.State = this; // Nothing to do. } internal override void ChangeStatePreparing( InternalEnlistment enlistment ) { // This enlistment was told to abort before being told to prepare } internal override void InternalAborted( InternalEnlistment enlistment ) { // Ignore this in case the enlistment gets here before // the transaction tells it to do so } internal override void InternalCommitted( InternalEnlistment enlistment ) { // Ignore this in case the enlistment gets here before // the transaction tells it to do so } internal override void InternalIndoubt(InternalEnlistment enlistment) { // Ignore this in case the enlistment gets here before // the transaction tells it to do so } internal override void InDoubt(InternalEnlistment enlistment, Exception e) { // Ignore this in case the enlistment gets here before // the transaction tells it to do so } } // At some point either early or late the enlistment responded ReadOnly internal class VolatileEnlistmentDone : VolatileEnlistmentEnded { internal override void EnterState( InternalEnlistment enlistment ) { // Set the enlistment state enlistment.State = this; // Nothing to do. } internal override void ChangeStatePreparing( InternalEnlistment enlistment ) { enlistment.CheckComplete(); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- HttpResponseWrapper.cs
- ProfilePropertySettings.cs
- GenericXmlSecurityTokenAuthenticator.cs
- CompositeDataBoundControl.cs
- DelegateSerializationHolder.cs
- DataGridTablesFactory.cs
- FlowLayoutSettings.cs
- Calendar.cs
- SessionEndedEventArgs.cs
- Debug.cs
- ECDiffieHellmanCngPublicKey.cs
- NativeRecognizer.cs
- Constraint.cs
- CSharpCodeProvider.cs
- XmlNodeChangedEventArgs.cs
- SerializationException.cs
- IFlowDocumentViewer.cs
- UndoManager.cs
- XpsFontSerializationService.cs
- FixedTextBuilder.cs
- SafeUserTokenHandle.cs
- PTProvider.cs
- GuidConverter.cs
- HttpListenerException.cs
- XmlArrayAttribute.cs
- SingleConverter.cs
- ImageKeyConverter.cs
- CompensationTokenData.cs
- InputMethod.cs
- ArrowControl.xaml.cs
- QueryParameter.cs
- CompositeControl.cs
- StoreContentChangedEventArgs.cs
- EventMappingSettingsCollection.cs
- AffineTransform3D.cs
- MapPathBasedVirtualPathProvider.cs
- StrongName.cs
- WebPartZoneCollection.cs
- OdbcReferenceCollection.cs
- XamlSerializerUtil.cs
- ParagraphVisual.cs
- ContentPathSegment.cs
- CodePageUtils.cs
- RegexInterpreter.cs
- WebSysDisplayNameAttribute.cs
- SessionStateModule.cs
- SqlTypesSchemaImporter.cs
- ComEventsHelper.cs
- FilePrompt.cs
- ContentPropertyAttribute.cs
- CodeVariableReferenceExpression.cs
- TemplatedWizardStep.cs
- ProgressBarRenderer.cs
- CodeIndexerExpression.cs
- InstanceData.cs
- ZipIOCentralDirectoryDigitalSignature.cs
- FormatConvertedBitmap.cs
- DocumentPageViewAutomationPeer.cs
- RSAOAEPKeyExchangeDeformatter.cs
- DataGridViewRow.cs
- ClientSideProviderDescription.cs
- KoreanLunisolarCalendar.cs
- UpdateManifestForBrowserApplication.cs
- RowParagraph.cs
- DataGridCellAutomationPeer.cs
- RoutingExtensionElement.cs
- DesignSurfaceManager.cs
- SortFieldComparer.cs
- LightweightCodeGenerator.cs
- InplaceBitmapMetadataWriter.cs
- DisposableCollectionWrapper.cs
- RepeatBehaviorConverter.cs
- StylusButtonEventArgs.cs
- PeerName.cs
- DataGridViewUtilities.cs
- Color.cs
- DEREncoding.cs
- TdsParserSessionPool.cs
- MatrixTransform.cs
- EndpointAddressAugust2004.cs
- MulticastDelegate.cs
- RoutedEventHandlerInfo.cs
- ReadOnlyHierarchicalDataSource.cs
- HandleDictionary.cs
- HttpFileCollectionBase.cs
- SiteMapNode.cs
- ApplicationId.cs
- UserControlFileEditor.cs
- PublishLicense.cs
- SiteMapProvider.cs
- HtmlElementErrorEventArgs.cs
- ErrorRuntimeConfig.cs
- Utils.cs
- DefaultTraceListener.cs
- Grid.cs
- NameTable.cs
- externdll.cs
- Memoizer.cs
- BaseWebProxyFinder.cs
- Camera.cs