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
- SaveFileDialog.cs
- BinaryFormatterWriter.cs
- SubtreeProcessor.cs
- SubtreeProcessor.cs
- XmlSchemaInferenceException.cs
- SQLRoleProvider.cs
- TargetControlTypeCache.cs
- Trace.cs
- TransactedBatchingElement.cs
- DoWorkEventArgs.cs
- Math.cs
- CommandField.cs
- SmiSettersStream.cs
- _emptywebproxy.cs
- TranslateTransform3D.cs
- SoapHeaderAttribute.cs
- DataGridCell.cs
- EncodingInfo.cs
- DesignerTransaction.cs
- Util.cs
- DataGrid.cs
- PeerTransportListenAddressConverter.cs
- StylusButton.cs
- TouchPoint.cs
- HttpCapabilitiesSectionHandler.cs
- GridViewDesigner.cs
- EntryPointNotFoundException.cs
- MenuItemBindingCollection.cs
- SoapFaultCodes.cs
- GroupByExpressionRewriter.cs
- SocketSettings.cs
- EndpointDiscoveryMetadata11.cs
- MoveSizeWinEventHandler.cs
- XamlReaderHelper.cs
- PropVariant.cs
- DeclarativeCatalogPartDesigner.cs
- SetterBaseCollection.cs
- EntityContainerEmitter.cs
- DefaultEventAttribute.cs
- RegionInfo.cs
- BooleanStorage.cs
- HtmlElementCollection.cs
- OdbcError.cs
- ClientTargetCollection.cs
- XXXOnTypeBuilderInstantiation.cs
- AppearanceEditorPart.cs
- ToolStripDropDownMenu.cs
- ObjectView.cs
- MsmqIntegrationAppDomainProtocolHandler.cs
- DefaultSerializationProviderAttribute.cs
- hwndwrapper.cs
- BitmapFrameDecode.cs
- AtomMaterializerLog.cs
- AppDomainManager.cs
- MemberDescriptor.cs
- SafeRightsManagementPubHandle.cs
- UrlMappingsModule.cs
- MembershipValidatePasswordEventArgs.cs
- PropertyGridEditorPart.cs
- PointConverter.cs
- ResourceExpressionBuilder.cs
- QueryableDataSource.cs
- DoubleLink.cs
- ApplicationServiceManager.cs
- TrustLevel.cs
- EllipseGeometry.cs
- DesignerSerializationManager.cs
- BStrWrapper.cs
- Attribute.cs
- ResXDataNode.cs
- DataBoundControl.cs
- CompoundFileDeflateTransform.cs
- DesignerCommandSet.cs
- ProxyFragment.cs
- BitmapSourceSafeMILHandle.cs
- InfoCardRSAOAEPKeyExchangeDeformatter.cs
- AuthenticationSection.cs
- AsyncInvokeOperation.cs
- ListViewTableRow.cs
- DateTimeOffsetStorage.cs
- dataobject.cs
- ParallelRangeManager.cs
- WindowsRegion.cs
- ConsoleEntryPoint.cs
- RegexStringValidator.cs
- DataGridViewCellFormattingEventArgs.cs
- _RegBlobWebProxyDataBuilder.cs
- IOException.cs
- Latin1Encoding.cs
- SecurityBindingElement.cs
- ProviderCollection.cs
- DispatchWrapper.cs
- MsmqHostedTransportManager.cs
- PrintDialog.cs
- BuildManager.cs
- DSACryptoServiceProvider.cs
- MethodRental.cs
- ErrorBehavior.cs
- DateTimeStorage.cs
- SelectedDatesCollection.cs