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
- FormViewInsertedEventArgs.cs
- BrowserCapabilitiesFactoryBase.cs
- WorkflowShape.cs
- QilSortKey.cs
- ItemsControl.cs
- HealthMonitoringSectionHelper.cs
- Decoder.cs
- Compiler.cs
- TextProperties.cs
- SystemSounds.cs
- ScriptManager.cs
- PeerUnsafeNativeMethods.cs
- TextControl.cs
- DocumentApplication.cs
- CompModSwitches.cs
- PersonalizationDictionary.cs
- DataTableTypeConverter.cs
- IUnknownConstantAttribute.cs
- TreeBuilder.cs
- BasicViewGenerator.cs
- ObjectListCommand.cs
- DynamicQueryStringParameter.cs
- RequiredFieldValidator.cs
- FormsAuthenticationCredentials.cs
- ServicePointManager.cs
- ChangeDirector.cs
- DocumentSequence.cs
- KnownIds.cs
- SqlUnionizer.cs
- HttpRuntime.cs
- VisualStyleRenderer.cs
- ComplexLine.cs
- JsonUriDataContract.cs
- ObjectSet.cs
- StringReader.cs
- Transform.cs
- TextTreeNode.cs
- XmlFormatWriterGenerator.cs
- ListComponentEditor.cs
- ArithmeticException.cs
- CodeIdentifier.cs
- TimeSpanValidator.cs
- GlyphsSerializer.cs
- ToolStripInSituService.cs
- DBCommandBuilder.cs
- objectquery_tresulttype.cs
- WebExceptionStatus.cs
- ObjectListFieldCollection.cs
- Schema.cs
- WebPartEditorOkVerb.cs
- XmlQualifiedNameTest.cs
- MessageLoggingFilterTraceRecord.cs
- WebBrowsableAttribute.cs
- TextBoxBase.cs
- AddressUtility.cs
- AlphabeticalEnumConverter.cs
- TCEAdapterGenerator.cs
- GuidConverter.cs
- QueryMatcher.cs
- NameNode.cs
- GridViewPageEventArgs.cs
- SQLConvert.cs
- CheckBoxBaseAdapter.cs
- BlurEffect.cs
- localization.cs
- hresults.cs
- WindowsGraphicsWrapper.cs
- ProcessInfo.cs
- HostedImpersonationContext.cs
- SHA384Managed.cs
- SiteMapNodeItemEventArgs.cs
- Point3DCollection.cs
- AutomationTextAttribute.cs
- XmlSecureResolver.cs
- PageAdapter.cs
- OleDbPropertySetGuid.cs
- DataSourceXmlSubItemAttribute.cs
- Activation.cs
- Material.cs
- BitmapEffect.cs
- ApplicationServicesHostFactory.cs
- InputScopeConverter.cs
- SqlDataSource.cs
- XmlQueryTypeFactory.cs
- XpsResourcePolicy.cs
- InfiniteIntConverter.cs
- ScrollContentPresenter.cs
- DecimalFormatter.cs
- OleDbPropertySetGuid.cs
- UnorderedHashRepartitionStream.cs
- TextViewSelectionProcessor.cs
- XmlSchemaAll.cs
- TransactionProtocolConverter.cs
- ServiceErrorHandler.cs
- AdjustableArrowCap.cs
- CheckBox.cs
- HttpModuleAction.cs
- SelectionWordBreaker.cs
- HttpHostedTransportConfiguration.cs
- SurrogateSelector.cs