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
- HitTestWithGeometryDrawingContextWalker.cs
- Header.cs
- PermissionAttributes.cs
- Tool.cs
- TokenBasedSetEnumerator.cs
- XmlCDATASection.cs
- BindingContext.cs
- List.cs
- ClientType.cs
- EditorServiceContext.cs
- ClientRolePrincipal.cs
- SourceFileBuildProvider.cs
- CodeTypeReferenceCollection.cs
- ArgumentValueSerializer.cs
- ToolStripSystemRenderer.cs
- BitmapEffectInputData.cs
- HwndSourceParameters.cs
- ReadOnlyAttribute.cs
- HttpListenerException.cs
- CanonicalizationDriver.cs
- DockProviderWrapper.cs
- FileDialog.cs
- Timer.cs
- SessionSwitchEventArgs.cs
- ConfigurationValues.cs
- compensatingcollection.cs
- Timer.cs
- Column.cs
- _AcceptOverlappedAsyncResult.cs
- ConsoleTraceListener.cs
- PointConverter.cs
- MultipleViewPattern.cs
- GcHandle.cs
- ParsedAttributeCollection.cs
- BindingOperations.cs
- ExpressionBindingCollection.cs
- DesignerActionGlyph.cs
- handlecollector.cs
- DeclarativeCatalogPartDesigner.cs
- ColumnBinding.cs
- DesignOnlyAttribute.cs
- SafeViewOfFileHandle.cs
- SafeRightsManagementEnvironmentHandle.cs
- XmlSchemaSimpleContent.cs
- _NegoState.cs
- FontCacheUtil.cs
- TableHeaderCell.cs
- Line.cs
- GradientBrush.cs
- ServerValidateEventArgs.cs
- ObservableCollection.cs
- MatcherBuilder.cs
- ResourceAttributes.cs
- ConstraintConverter.cs
- HTTPNotFoundHandler.cs
- SqlDataSourceView.cs
- GroupDescription.cs
- BoundPropertyEntry.cs
- WebPartEventArgs.cs
- Membership.cs
- SessionStateItemCollection.cs
- PeerApplication.cs
- BitmapDownload.cs
- SyntaxCheck.cs
- KoreanLunisolarCalendar.cs
- LostFocusEventManager.cs
- UnsafeNativeMethodsTablet.cs
- DrawListViewSubItemEventArgs.cs
- PlaceHolder.cs
- LifetimeServices.cs
- URL.cs
- UserControlAutomationPeer.cs
- BaseValidator.cs
- FormatException.cs
- OperationAbortedException.cs
- _NegotiateClient.cs
- PeerTransportListenAddressValidatorAttribute.cs
- DataViewListener.cs
- XPathPatternBuilder.cs
- DateTime.cs
- SizeAnimation.cs
- AdornerPresentationContext.cs
- HttpCachePolicyElement.cs
- Label.cs
- XPathAncestorIterator.cs
- OrderPreservingPipeliningMergeHelper.cs
- Pair.cs
- AutomationEventArgs.cs
- OracleConnectionString.cs
- EditorZoneBase.cs
- EventHandlerList.cs
- DataGridViewComboBoxCell.cs
- WebPartConnectVerb.cs
- StylusButtonEventArgs.cs
- FileLoadException.cs
- IntSecurity.cs
- WebPartDisplayModeCancelEventArgs.cs
- CacheChildrenQuery.cs
- TrackingStringDictionary.cs
- InstancePersistenceException.cs