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
- SoapCodeExporter.cs
- TemplateBindingExpressionConverter.cs
- TextReader.cs
- HttpRequest.cs
- ContravarianceAdapter.cs
- _UriSyntax.cs
- PublisherMembershipCondition.cs
- ScrollBar.cs
- ObjectDataSourceFilteringEventArgs.cs
- NumericExpr.cs
- DocumentSchemaValidator.cs
- UidManager.cs
- ExpressionsCollectionEditor.cs
- JsonReader.cs
- XmlKeywords.cs
- Int64.cs
- Util.cs
- DataGridParentRows.cs
- SystemBrushes.cs
- DrawingAttributeSerializer.cs
- XmlEntity.cs
- AsymmetricKeyExchangeDeformatter.cs
- DetailsViewPagerRow.cs
- TextCompositionEventArgs.cs
- PermissionRequestEvidence.cs
- EntityDataSourceWizardForm.cs
- StyleSelector.cs
- XmlQueryType.cs
- DbConnectionClosed.cs
- TreeNodeBindingCollection.cs
- HtmlHead.cs
- HtmlElement.cs
- AppDomainCompilerProxy.cs
- WinCategoryAttribute.cs
- tibetanshape.cs
- QuadraticBezierSegment.cs
- AmbiguousMatchException.cs
- NTAccount.cs
- EntitySqlQueryCacheEntry.cs
- SqlUserDefinedTypeAttribute.cs
- QilLiteral.cs
- RowTypeElement.cs
- XmlSchemaFacet.cs
- PropertyBuilder.cs
- GraphicsContainer.cs
- SoapMessage.cs
- ToolboxItemSnapLineBehavior.cs
- InertiaExpansionBehavior.cs
- CodeGotoStatement.cs
- WMIGenerator.cs
- OdbcDataAdapter.cs
- SimpleApplicationHost.cs
- NoneExcludedImageIndexConverter.cs
- SqlDataSourceCache.cs
- ColumnMap.cs
- _TransmitFileOverlappedAsyncResult.cs
- CodeAttributeArgumentCollection.cs
- WsdlBuildProvider.cs
- WebPartZoneBase.cs
- RotateTransform3D.cs
- RuleEngine.cs
- ColumnHeaderCollectionEditor.cs
- TableDetailsRow.cs
- SqlDelegatedTransaction.cs
- CorePropertiesFilter.cs
- EntityStoreSchemaFilterEntry.cs
- SqlRowUpdatedEvent.cs
- SchemaCollectionPreprocessor.cs
- ObjectStateManager.cs
- StateFinalizationActivity.cs
- HotSpot.cs
- StandardCommands.cs
- VerificationAttribute.cs
- IteratorFilter.cs
- FactorySettingsElement.cs
- PerfCounterSection.cs
- ImageSource.cs
- PropertyStore.cs
- PrincipalPermission.cs
- SqlMethods.cs
- BindingEntityInfo.cs
- Stylesheet.cs
- RuntimeDelegateArgument.cs
- ObjectStateEntryBaseUpdatableDataRecord.cs
- BitHelper.cs
- RemoteWebConfigurationHost.cs
- AnnotationHelper.cs
- ColorConvertedBitmapExtension.cs
- StyleTypedPropertyAttribute.cs
- BooleanFacetDescriptionElement.cs
- OdbcStatementHandle.cs
- serverconfig.cs
- PrintDialogException.cs
- DataPager.cs
- XmlValidatingReaderImpl.cs
- FontWeight.cs
- SoapFault.cs
- KeyTimeConverter.cs
- AutomationEventArgs.cs
- UpDownEvent.cs