Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / tx / System / Transactions / Enlistment.cs / 1305376 / Enlistment.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; using System.Transactions.Diagnostics; internal interface IPromotedEnlistment { void EnlistmentDone(); void Prepared(); void ForceRollback(); void ForceRollback(Exception e); void Committed(); void Aborted(); void Aborted(Exception e); void InDoubt(); void InDoubt(Exception e); byte [] GetRecoveryInformation(); InternalEnlistment InternalEnlistment { get; set; } } // // InternalEnlistment by itself can support a Phase0 volatile enlistment. // There are derived classes to support durable, phase1 volatile & PSPE // enlistments. // class InternalEnlistment : ISinglePhaseNotificationInternal { // Storage for the state of the enlistment. internal EnlistmentState twoPhaseState; // Interface implemented by the enlistment owner for notifications protected IEnlistmentNotification twoPhaseNotifications; // Store a reference to the single phase notification interface in case // the enlisment supports it. protected ISinglePhaseNotification singlePhaseNotifications; // Reference to the containing transaction. protected InternalTransaction transaction; // Reference to the lightweight transaction. Transaction atomicTransaction; // The EnlistmentTraceIdentifier for this enlistment. private EnlistmentTraceIdentifier traceIdentifier; // Unique value amongst all enlistments for a given internal transaction. int enlistmentId; // Parent Enlistment Object Enlistment enlistment; PreparingEnlistment preparingEnlistment; SinglePhaseEnlistment singlePhaseEnlistment; // If this enlistment is promoted store the object it delegates to. IPromotedEnlistment promotedEnlistment; // For Recovering Enlistments protected InternalEnlistment( Enlistment enlistment, IEnlistmentNotification twoPhaseNotifications ) { Debug.Assert(this is RecoveringInternalEnlistment, "this is RecoveringInternalEnlistment"); this.enlistment = enlistment; this.twoPhaseNotifications = twoPhaseNotifications; this.enlistmentId = 1; this.traceIdentifier = EnlistmentTraceIdentifier.Empty; } // For Promotable Enlistments protected InternalEnlistment( Enlistment enlistment, InternalTransaction transaction, Transaction atomicTransaction ) { Debug.Assert(this is PromotableInternalEnlistment, "this is PromotableInternalEnlistment"); this.enlistment = enlistment; this.transaction = transaction; this.atomicTransaction = atomicTransaction; this.enlistmentId = transaction.enlistmentCount++; this.traceIdentifier = EnlistmentTraceIdentifier.Empty; } internal InternalEnlistment( Enlistment enlistment, InternalTransaction transaction, IEnlistmentNotification twoPhaseNotifications, ISinglePhaseNotification singlePhaseNotifications, Transaction atomicTransaction ) { this.enlistment = enlistment; this.transaction = transaction; this.twoPhaseNotifications = twoPhaseNotifications; this.singlePhaseNotifications = singlePhaseNotifications; this.atomicTransaction = atomicTransaction; this.enlistmentId = transaction.enlistmentCount++; this.traceIdentifier = EnlistmentTraceIdentifier.Empty; } internal InternalEnlistment( Enlistment enlistment, IEnlistmentNotification twoPhaseNotifications, InternalTransaction transaction, Transaction atomicTransaction ) { this.enlistment = enlistment; this.twoPhaseNotifications = twoPhaseNotifications; this.transaction = transaction; this.atomicTransaction = atomicTransaction; } internal EnlistmentState State { get { return this.twoPhaseState; } set { this.twoPhaseState = value; } } internal Enlistment Enlistment { get { return this.enlistment; } } internal PreparingEnlistment PreparingEnlistment { get { if( this.preparingEnlistment == null ) { // If there is a ---- here one of the objects would simply be garbage collected. this.preparingEnlistment = new PreparingEnlistment( this ); } return this.preparingEnlistment; } } internal SinglePhaseEnlistment SinglePhaseEnlistment { get { if( this.singlePhaseEnlistment == null ) { // If there is a ---- here one of the objects would simply be garbage collected. this.singlePhaseEnlistment = new SinglePhaseEnlistment( this ); } return this.singlePhaseEnlistment; } } internal InternalTransaction Transaction { get { return this.transaction; } } internal virtual object SyncRoot { get { Debug.Assert( this.transaction != null, "this.transaction != null" ); return this.transaction; } } internal IEnlistmentNotification EnlistmentNotification { get { return this.twoPhaseNotifications; } } internal ISinglePhaseNotification SinglePhaseNotification { get { return this.singlePhaseNotifications; } } internal virtual IPromotableSinglePhaseNotification PromotableSinglePhaseNotification { get { Debug.Assert(false, "PromotableSinglePhaseNotification called for a non promotable enlistment."); throw new NotImplementedException(); } } internal IPromotedEnlistment PromotedEnlistment { get { return this.promotedEnlistment; } set { this.promotedEnlistment = value; } } internal EnlistmentTraceIdentifier EnlistmentTraceId { get { if ( this.traceIdentifier == EnlistmentTraceIdentifier.Empty ) { lock( this.SyncRoot ) { if ( this.traceIdentifier == EnlistmentTraceIdentifier.Empty ) { EnlistmentTraceIdentifier temp; if ( null != this.atomicTransaction ) { temp = new EnlistmentTraceIdentifier( Guid.Empty, this.atomicTransaction.TransactionTraceId, this.enlistmentId ); } else { temp = new EnlistmentTraceIdentifier( Guid.Empty, new TransactionTraceIdentifier( InternalTransaction.InstanceIdentifier + Convert.ToString( Interlocked.Increment( ref InternalTransaction.nextHash ), CultureInfo.InvariantCulture ), 0 ), this.enlistmentId ); } Thread.MemoryBarrier(); this.traceIdentifier = temp; } } } return this.traceIdentifier; } } internal virtual void FinishEnlistment() { // Note another enlistment finished. this.Transaction.phase0Volatiles.preparedVolatileEnlistments++; CheckComplete(); } internal virtual void CheckComplete() { // Make certain we increment the right list. Debug.Assert( this.Transaction.phase0Volatiles.preparedVolatileEnlistments <= this.Transaction.phase0Volatiles.volatileEnlistmentCount + this.Transaction.phase0Volatiles.dependentClones ); // Check to see if all of the volatile enlistments are done. if( this.Transaction.phase0Volatiles.preparedVolatileEnlistments == this.Transaction.phase0VolatileWaveCount + this.Transaction.phase0Volatiles.dependentClones ) { this.Transaction.State.Phase0VolatilePrepareDone( this.Transaction ); } } internal virtual Guid ResourceManagerIdentifier { get { Debug.Assert(false, "ResourceManagerIdentifier called for non durable enlistment"); throw new NotImplementedException(); } } void ISinglePhaseNotificationInternal.SinglePhaseCommit( IPromotedEnlistment singlePhaseEnlistment ) { bool spcCommitted = false; this.promotedEnlistment = singlePhaseEnlistment; try { this.singlePhaseNotifications.SinglePhaseCommit(this.SinglePhaseEnlistment); spcCommitted = true; } finally { if (!spcCommitted) { this.SinglePhaseEnlistment.InDoubt(); } } } void IEnlistmentNotificationInternal.Prepare( IPromotedEnlistment preparingEnlistment ) { this.promotedEnlistment = preparingEnlistment; this.twoPhaseNotifications.Prepare( this.PreparingEnlistment ); } void IEnlistmentNotificationInternal.Commit( IPromotedEnlistment enlistment ) { this.promotedEnlistment = enlistment; this.twoPhaseNotifications.Commit( this.Enlistment ); } void IEnlistmentNotificationInternal.Rollback( IPromotedEnlistment enlistment ) { this.promotedEnlistment = enlistment; this.twoPhaseNotifications.Rollback( this.Enlistment ); } void IEnlistmentNotificationInternal.InDoubt( IPromotedEnlistment enlistment ) { this.promotedEnlistment = enlistment; this.twoPhaseNotifications.InDoubt( this.Enlistment ); } } class DurableInternalEnlistment : InternalEnlistment { // Resource Manager Identifier for this enlistment if it is durable internal Guid resourceManagerIdentifier; internal DurableInternalEnlistment( Enlistment enlistment, Guid resourceManagerIdentifier, InternalTransaction transaction, IEnlistmentNotification twoPhaseNotifications, ISinglePhaseNotification singlePhaseNotifications, Transaction atomicTransaction ) : base(enlistment, transaction, twoPhaseNotifications, singlePhaseNotifications, atomicTransaction) { this.resourceManagerIdentifier = resourceManagerIdentifier; } protected DurableInternalEnlistment( Enlistment enlistment, IEnlistmentNotification twoPhaseNotifications ) : base(enlistment, twoPhaseNotifications) { } internal override Guid ResourceManagerIdentifier { get { return resourceManagerIdentifier; } } } // // Since RecoveringInternalEnlistment does not have a transaction it must take // a separate object as its [....] root. // class RecoveringInternalEnlistment : DurableInternalEnlistment { object syncRoot; internal RecoveringInternalEnlistment( Enlistment enlistment, IEnlistmentNotification twoPhaseNotifications, object syncRoot ) : base(enlistment, twoPhaseNotifications) { this.syncRoot = syncRoot; } internal override object SyncRoot { get { return this.syncRoot; } } } class PromotableInternalEnlistment : InternalEnlistment { // This class acts as the durable single phase enlistment for a // promotable single phase enlistment. IPromotableSinglePhaseNotification promotableNotificationInterface; internal PromotableInternalEnlistment( Enlistment enlistment, InternalTransaction transaction, IPromotableSinglePhaseNotification promotableSinglePhaseNotification, Transaction atomicTransaction ) : base(enlistment, transaction, atomicTransaction) { this.promotableNotificationInterface = promotableSinglePhaseNotification; } internal override IPromotableSinglePhaseNotification PromotableSinglePhaseNotification { get { return this.promotableNotificationInterface; } } } // This class supports volatile enlistments // internal class Phase1VolatileEnlistment : InternalEnlistment { public Phase1VolatileEnlistment( Enlistment enlistment, InternalTransaction transaction, IEnlistmentNotification twoPhaseNotifications, ISinglePhaseNotification singlePhaseNotifications, Transaction atomicTransaction ) : base( enlistment, transaction, twoPhaseNotifications, singlePhaseNotifications, atomicTransaction ) { } internal override void FinishEnlistment() { // Note another enlistment finished. this.transaction.phase1Volatiles.preparedVolatileEnlistments++; CheckComplete(); } internal override void CheckComplete() { // Make certain we increment the right list. Debug.Assert( this.transaction.phase1Volatiles.preparedVolatileEnlistments <= this.transaction.phase1Volatiles.volatileEnlistmentCount + this.transaction.phase1Volatiles.dependentClones ); // Check to see if all of the volatile enlistments are done. if( this.transaction.phase1Volatiles.preparedVolatileEnlistments == this.transaction.phase1Volatiles.volatileEnlistmentCount + this.transaction.phase1Volatiles.dependentClones ) { this.transaction.State.Phase1VolatilePrepareDone( this.transaction ); } } } public class Enlistment { // Interface for communicating with the state machine. internal InternalEnlistment internalEnlistment; internal Enlistment( InternalEnlistment internalEnlistment ) { this.internalEnlistment = internalEnlistment; } internal Enlistment( Guid resourceManagerIdentifier, InternalTransaction transaction, IEnlistmentNotification twoPhaseNotifications, ISinglePhaseNotification singlePhaseNotifications, Transaction atomicTransaction ) { this.internalEnlistment = new DurableInternalEnlistment( this, resourceManagerIdentifier, transaction, twoPhaseNotifications, singlePhaseNotifications, atomicTransaction ); } internal Enlistment( InternalTransaction transaction, IEnlistmentNotification twoPhaseNotifications, ISinglePhaseNotification singlePhaseNotifications, Transaction atomicTransaction, EnlistmentOptions enlistmentOptions ) { if( (enlistmentOptions & EnlistmentOptions.EnlistDuringPrepareRequired) != 0 ) { this.internalEnlistment = new InternalEnlistment( this, transaction, twoPhaseNotifications, singlePhaseNotifications, atomicTransaction ); } else { this.internalEnlistment = new Phase1VolatileEnlistment( this, transaction, twoPhaseNotifications, singlePhaseNotifications, atomicTransaction ); } } // This constructor is for a promotable single phase enlistment. internal Enlistment( InternalTransaction transaction, IPromotableSinglePhaseNotification promotableSinglePhaseNotification, Transaction atomicTransaction ) { this.internalEnlistment = new PromotableInternalEnlistment( this, transaction, promotableSinglePhaseNotification, atomicTransaction ); } internal Enlistment( IEnlistmentNotification twoPhaseNotifications, InternalTransaction transaction, Transaction atomicTransaction ) { this.internalEnlistment = new InternalEnlistment( this, twoPhaseNotifications, transaction, atomicTransaction ); } internal Enlistment( IEnlistmentNotification twoPhaseNotifications, object syncRoot ) { this.internalEnlistment = new RecoveringInternalEnlistment( this, twoPhaseNotifications, syncRoot ); } public void Done() { if ( DiagnosticTrace.Verbose ) { MethodEnteredTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ), "Enlistment.Done" ); EnlistmentCallbackPositiveTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ), this.internalEnlistment.EnlistmentTraceId, EnlistmentCallback.Done ); } lock( this.internalEnlistment.SyncRoot ) { this.internalEnlistment.State.EnlistmentDone( this.internalEnlistment ); } if ( DiagnosticTrace.Verbose ) { MethodExitedTraceRecord.Trace( SR.GetString( SR.TraceSourceLtm ), "Enlistment.Done" ); } } internal InternalEnlistment InternalEnlistment { get { return this.internalEnlistment; } } } } // 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
- SystemThemeKey.cs
- IImplicitResourceProvider.cs
- ApplicationTrust.cs
- TreeNodeStyleCollection.cs
- NamedPermissionSet.cs
- TempFiles.cs
- X509CertificateStore.cs
- Item.cs
- VisualStyleElement.cs
- LocalizationParserHooks.cs
- InternalRelationshipCollection.cs
- SessionEndedEventArgs.cs
- IdentityModelDictionary.cs
- PropertyBuilder.cs
- MarginsConverter.cs
- BitmapVisualManager.cs
- DocumentOutline.cs
- CompilationLock.cs
- PermissionSet.cs
- GeometryGroup.cs
- Activity.cs
- XmlAutoDetectWriter.cs
- ManipulationInertiaStartingEventArgs.cs
- XmlSchemaImport.cs
- CompositionTarget.cs
- RequestCacheManager.cs
- MatrixAnimationUsingKeyFrames.cs
- Splitter.cs
- ArrayConverter.cs
- Panel.cs
- IntranetCredentialPolicy.cs
- SizeValueSerializer.cs
- ObjectDataSourceView.cs
- CodeValidator.cs
- ApplicationTrust.cs
- OleDbConnectionInternal.cs
- Transform.cs
- XslVisitor.cs
- BitmapEffect.cs
- ConfigViewGenerator.cs
- SwitchLevelAttribute.cs
- ButtonBase.cs
- SmiSettersStream.cs
- ReadOnlyHierarchicalDataSource.cs
- TcpConnectionPoolSettingsElement.cs
- PaperSize.cs
- CodeTypeDeclarationCollection.cs
- SequenceNumber.cs
- NativeMethods.cs
- FontCacheUtil.cs
- Span.cs
- RectangleHotSpot.cs
- RawStylusInputCustomDataList.cs
- SignerInfo.cs
- Listener.cs
- SemaphoreSecurity.cs
- BitmapFrame.cs
- StyleCollectionEditor.cs
- ObjectListSelectEventArgs.cs
- OleDbPermission.cs
- SelectedGridItemChangedEvent.cs
- Literal.cs
- RegisteredExpandoAttribute.cs
- RijndaelCryptoServiceProvider.cs
- SqlTopReducer.cs
- MediaElement.cs
- RecommendedAsConfigurableAttribute.cs
- ClientConvert.cs
- TextDecoration.cs
- HttpResponse.cs
- ValidateNames.cs
- XmlSchemaInclude.cs
- QueueProcessor.cs
- SystemWebExtensionsSectionGroup.cs
- DropTarget.cs
- Int16Storage.cs
- InlineCollection.cs
- LateBoundChannelParameterCollection.cs
- SqlDataReaderSmi.cs
- EntityDescriptor.cs
- SafeEventLogWriteHandle.cs
- DependencyPropertyChangedEventArgs.cs
- HostedElements.cs
- SmtpLoginAuthenticationModule.cs
- OracleBFile.cs
- ManipulationBoundaryFeedbackEventArgs.cs
- ClockController.cs
- XamlSerializerUtil.cs
- LabelAutomationPeer.cs
- IList.cs
- UIElement.cs
- Label.cs
- DerivedKeySecurityToken.cs
- ExtendedPropertyDescriptor.cs
- EntityWrapper.cs
- DBBindings.cs
- EmptyImpersonationContext.cs
- SwitchAttribute.cs
- Terminate.cs
- DispatcherProcessingDisabled.cs