Code:
/ 4.0 / 4.0 / untmp / 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.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- _CacheStreams.cs
- XmlSerializerSection.cs
- ConnectionManagementElementCollection.cs
- ControlCachePolicy.cs
- DescriptionAttribute.cs
- ContainerAction.cs
- MailDefinition.cs
- SectionUpdates.cs
- ConfigurationManagerInternal.cs
- TableRow.cs
- PropertyInfoSet.cs
- CornerRadius.cs
- ReflectTypeDescriptionProvider.cs
- FigureParaClient.cs
- HeaderPanel.cs
- DragStartedEventArgs.cs
- BooleanSwitch.cs
- TextureBrush.cs
- ComNativeDescriptor.cs
- ComponentDispatcherThread.cs
- EdmSchemaAttribute.cs
- ControlUtil.cs
- CreateDataSourceDialog.cs
- RayMeshGeometry3DHitTestResult.cs
- Propagator.Evaluator.cs
- validationstate.cs
- UIElement.cs
- ListChangedEventArgs.cs
- EdmScalarPropertyAttribute.cs
- EditorServiceContext.cs
- IDataContractSurrogate.cs
- FormsAuthenticationUserCollection.cs
- DataBindingExpressionBuilder.cs
- XPathMultyIterator.cs
- wgx_render.cs
- Listbox.cs
- diagnosticsswitches.cs
- TemplateBindingExtensionConverter.cs
- GridEntryCollection.cs
- LabelTarget.cs
- Tag.cs
- FontInfo.cs
- Journaling.cs
- LinqDataSourceEditData.cs
- ExtenderProvidedPropertyAttribute.cs
- SimpleTextLine.cs
- SinglePageViewer.cs
- FileSecurity.cs
- HMACSHA1.cs
- SimpleLine.cs
- EventEntry.cs
- IImplicitResourceProvider.cs
- AspCompat.cs
- DependencyPropertyAttribute.cs
- InnerItemCollectionView.cs
- XmlILConstructAnalyzer.cs
- CodeRegionDirective.cs
- ActivityValidator.cs
- IndicFontClient.cs
- ObjectNavigationPropertyMapping.cs
- RelationshipEndMember.cs
- ReadOnlyCollectionBase.cs
- GenericWebPart.cs
- SqlFormatter.cs
- DropDownList.cs
- StringValidator.cs
- DefaultAssemblyResolver.cs
- DataGridViewColumnConverter.cs
- StyleSheetComponentEditor.cs
- KeyValueInternalCollection.cs
- Hashtable.cs
- CodeTypeDeclarationCollection.cs
- _NtlmClient.cs
- Point3DConverter.cs
- SignatureDescription.cs
- RepeatBehaviorConverter.cs
- NativeRightsManagementAPIsStructures.cs
- DynamicEntity.cs
- JoinQueryOperator.cs
- SerializerWriterEventHandlers.cs
- JapaneseLunisolarCalendar.cs
- RuleRef.cs
- DbConnectionPool.cs
- Simplifier.cs
- DateBoldEvent.cs
- LocalizableResourceBuilder.cs
- Expander.cs
- TableParaClient.cs
- hwndwrapper.cs
- SymmetricAlgorithm.cs
- FileNotFoundException.cs
- CultureTableRecord.cs
- HtmlFormParameterWriter.cs
- WebPartConnectionsDisconnectVerb.cs
- FileEnumerator.cs
- AsymmetricAlgorithm.cs
- RectAnimationBase.cs
- Point.cs
- FrameworkRichTextComposition.cs
- TableSectionStyle.cs