Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / TransactionBridge / Microsoft / Transactions / Wsat / StateMachines / State.cs / 1 / State.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- // This file contains the base class for all states in all state machines using System; using System.ServiceModel.Channels; using System.Diagnostics; using System.Globalization; using System.ServiceModel; using Microsoft.Transactions.Bridge; using Microsoft.Transactions.Wsat.Messaging; using Microsoft.Transactions.Wsat.InputOutput; using Microsoft.Transactions.Wsat.Protocol; using Fault = Microsoft.Transactions.Wsat.Messaging.Fault; using DiagnosticUtility = Microsoft.Transactions.Bridge.DiagnosticUtility; namespace Microsoft.Transactions.Wsat.StateMachines { // // States from which non-abstract states should inherit // abstract class InactiveState : State { protected InactiveState (ProtocolState state) : base (state) {} } abstract class ActiveState : State { protected ActiveState (ProtocolState state) : base (state) {} } abstract class DecidedState : State { protected DecidedState (ProtocolState state) : base (state) {} } abstract class TerminalState : State { protected TerminalState (ProtocolState state) : base (state) { } public override void Enter (StateMachine stateMachine) { base.Enter (stateMachine); // Clean up any state the state machine is holding open. This may include removing // the transaction and its associated resources from all global lookup tables stateMachine.Cleanup(); } } abstract class State : IIncomingEventSink { protected ProtocolState state; protected State (ProtocolState state) { this.state = state; } public override string ToString() { return this.GetType().Name; } // // Interface // public virtual void Enter (StateMachine stateMachine) { // Do nothing } public virtual void Leave (StateMachine stateMachine) { // Do nothing } // // Activation events // public virtual void OnEvent(MsgCreateTransactionEvent e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException()); } public virtual void OnEvent(MsgEnlistTransactionEvent e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException()); } public virtual void OnEvent(TmCreateTransactionResponseEvent e) { InvalidTransactionManagerEvent(e); } public virtual void OnEvent(TmEnlistTransactionResponseEvent e) { InvalidTransactionManagerEvent(e); } // // Registration events // public virtual void OnEvent(MsgRegisterCompletionEvent e) { InvalidRegisterCompletionMessage(e); } public virtual void OnEvent(MsgRegisterDurableResponseEvent e) { InvalidRegistrationCoordinatorMessage(e); } public virtual void OnEvent(MsgRegisterVolatileResponseEvent e) { InvalidRegistrationCoordinatorMessage(e); } public virtual void OnEvent(MsgRegistrationCoordinatorFaultEvent e) { // We need the CoordinatorRegistrationFailedFault only // for v1.0. For v1.1 we send the default ContextManager.Fault, // which is CannotCreateContext. if (this.state.ProtocolVersion == ProtocolVersion.Version10 && e.Coordinator.ContextManager != null) { Fault fault = CoordinatorRegistrationFailedFault.CreateFault(e.Fault); e.Coordinator.ContextManager.Fault = fault; } InvalidFaultEvent(e, e.Coordinator, e.Fault); } public virtual void OnEvent(MsgRegistrationCoordinatorSendFailureEvent e) { // We need the CoordinatorRegistrationFailedFault only // for v1.0. For v1.1 we send the default ContextManager.Fault, // which is CannotCreateContext. if (this.state.ProtocolVersion == ProtocolVersion.Version10 && e.Coordinator.ContextManager != null) { Fault fault = CoordinatorRegistrationFailedFault.CreateFault(null); e.Coordinator.ContextManager.Fault = fault; } InvalidSendMessageFailureEvent(e, e.Coordinator); } public virtual void OnEvent(TmRegisterResponseEvent e) { InvalidTransactionManagerEvent(e); } public virtual void OnEvent(TmSubordinateRegisterResponseEvent e) { InvalidTransactionManagerEvent(e); } public virtual void OnEvent(TmEnlistPrePrepareEvent e) { InvalidTransactionManagerEvent(e); } // // Completion events // public virtual void OnEvent(MsgCompletionCommitEvent e) { InvalidCompletionMessage(e); } public virtual void OnEvent(MsgCompletionRollbackEvent e) { InvalidCompletionMessage(e); } public virtual void OnEvent(TmCompletionCommitResponseEvent e) { InvalidTransactionManagerEvent(e); } public virtual void OnEvent(TmCompletionRollbackResponseEvent e) { InvalidTransactionManagerEvent(e); } // // TwoPhaseCommit // public virtual void OnEvent(MsgVolatilePrepareEvent e) { InvalidVolatileCoordinatorMessage(e); } public virtual void OnEvent(MsgDurablePrepareEvent e) { InvalidDurableCoordinatorMessage(e); } public virtual void OnEvent(MsgVolatileCommitEvent e) { InvalidVolatileCoordinatorMessage(e); } public virtual void OnEvent(MsgDurableCommitEvent e) { InvalidDurableCoordinatorMessage(e); } public virtual void OnEvent(MsgVolatileRollbackEvent e) { InvalidVolatileCoordinatorMessage(e); } public virtual void OnEvent(MsgDurableRollbackEvent e) { InvalidDurableCoordinatorMessage(e); } public virtual void OnEvent(MsgDurableCoordinatorFaultEvent e) { InvalidFaultEvent(e, e.Coordinator, e.Fault); } public void OnEvent(MsgVolatileCoordinatorFaultEvent e) { InvalidFaultEvent(e, e.VolatileCoordinator, e.Fault); } public virtual void OnEvent(MsgDurableCoordinatorSendFailureEvent e) { InvalidSendMessageFailureEvent(e, e.Coordinator); } public virtual void OnEvent(MsgVolatileCoordinatorSendFailureEvent e) { InvalidSendMessageFailureEvent(e, e.VolatileCoordinator); } public virtual void OnEvent(MsgPreparedEvent e) { InvalidParticipantMessage(e); } public virtual void OnEvent(MsgAbortedEvent e) { InvalidParticipantMessage(e); } public virtual void OnEvent(MsgReadOnlyEvent e) { InvalidParticipantMessage(e); } public virtual void OnEvent(MsgCommittedEvent e) { InvalidParticipantMessage(e); } public virtual void OnEvent(MsgReplayEvent e) { InvalidParticipantMessage(e); } public virtual void OnEvent(MsgParticipantFaultEvent e) { InvalidParticipantFaultEvent(e, e.Participant); } public virtual void OnEvent(MsgParticipantSendFailureEvent e) { InvalidSendMessageFailureEvent(e, e.Participant); } public virtual void OnEvent(TmPrePrepareResponseEvent e) { InvalidTransactionManagerEvent(e); } public virtual void OnEvent(TmPrepareResponseEvent e) { InvalidTransactionManagerEvent(e); } public virtual void OnEvent(TmCommitResponseEvent e) { InvalidTransactionManagerEvent(e); } public virtual void OnEvent(TmRollbackResponseEvent e) { InvalidTransactionManagerEvent(e); } public virtual void OnEvent(TmSinglePhaseCommitEvent e) { InvalidTransactionManagerEvent(e); } public virtual void OnEvent(TmCommitEvent e) { InvalidTransactionManagerEvent(e); } public virtual void OnEvent(TmRollbackEvent e) { InvalidTransactionManagerEvent(e); } public virtual void OnEvent(TmParticipantForgetEvent e) { InvalidTransactionManagerEvent(e); } public virtual void OnEvent(TmPrePrepareEvent e) { InvalidTransactionManagerEvent(e); } public virtual void OnEvent(TmPrepareEvent e) { InvalidTransactionManagerEvent(e); } public virtual void OnEvent(TmRejoinEvent e) { InvalidTransactionManagerEvent(e); } public virtual void OnEvent(TmReplayEvent e) { InvalidTransactionManagerEvent(e); } public virtual void OnEvent(TmCoordinatorForgetEvent e) { InvalidTransactionManagerEvent(e); } public virtual void OnEvent(TmAsyncRollbackEvent e) { InvalidTransactionManagerEvent(e); } // // Timers // public virtual void OnEvent(TimerCoordinatorEvent e) { InvalidTimerEvent(e); } public virtual void OnEvent(TimerParticipantEvent e) { InvalidTimerEvent(e); } // // Internal events // public virtual void OnEvent(InternalEnlistSubordinateTransactionEvent e) { InvalidInternalEvent(e); } // // Transaction context events // public virtual void OnEvent(TransactionContextEnlistTransactionEvent e) { InvalidInternalEvent(e); } public virtual void OnEvent(TransactionContextCreatedEvent e) { InvalidInternalEvent(e); } public virtual void OnEvent(TransactionContextTransactionDoneEvent e) { InvalidInternalEvent(e); } //////////////////////////// // Invalid event handling // //////////////////////////// void InvalidEventFailfast (SynchronizationEvent e) { string text = string.Format(CultureInfo.InvariantCulture, "Failfasting due to unexpected event {0} for state {1}", e, this); // For some unhandled events, we deliberately FailFast. This function // does that work. DiagnosticUtility.FailFast(text); } void InvalidTransactionManagerEvent(SynchronizationEvent e) { TraceInvalidEvent(e, true); InvalidEventFailfast(e); } void InvalidRegisterCompletionMessage(MsgRegisterCompletionEvent e) { TraceInvalidEvent(e, false); TryToAbortTransaction(e, e.Completion); if (RegisterParticipantFailureRecord.ShouldTrace) { RegisterParticipantFailureRecord.Trace( e.Completion.EnlistmentId, e.Completion.Enlistment.RemoteTransactionId, ControlProtocol.Completion, e.ParticipantService, SR.GetString(SR.RegisterFailureInvalidState, e.StateMachine.State.ToString()), this.state.ProtocolVersion ); } state.RegistrationCoordinator.SendFault(e.Result, this.state.Faults.InvalidState); } void InvalidRegistrationCoordinatorMessage(MsgRegisterDurableResponseEvent e) { TraceInvalidEvent(e, false); TryToAbortTransaction(e, e.Coordinator); } void InvalidRegistrationCoordinatorMessage(MsgRegisterVolatileResponseEvent e) { TraceInvalidEvent(e, false); TryToAbortTransaction(e, e.VolatileCoordinator); } void InvalidCompletionMessage(CompletionParticipantEvent e) { TraceInvalidEvent(e, false); TryToAbortTransaction(e, e.Completion); state.CompletionCoordinator.SendFault(e.FaultTo, e.MessageId, this.state.Faults.InvalidState); } void InvalidParticipantMessage(TwoPhaseCommitParticipantEvent e) { TraceInvalidEvent(e, false); TryToAbortTransaction(e, e.Participant); state.TwoPhaseCommitCoordinator.SendFault(e.FaultTo, e.MessageId, this.state.Faults.InvalidState); } void InvalidDurableCoordinatorMessage(DurableTwoPhaseCommitCoordinatorEvent e) { TraceInvalidEvent(e, false); TryToAbortTransaction(e, e.Coordinator); TrySendFault(e, this.state.Faults.InvalidState); } void InvalidVolatileCoordinatorMessage(VolatileTwoPhaseCommitCoordinatorEvent e) { TraceInvalidEvent(e, false); TryToAbortTransaction(e, e.VolatileCoordinator); TrySendFault(e, this.state.Faults.InvalidState); } void InvalidFaultEvent(SynchronizationEvent e, TransactionEnlistment enlistment, MessageFault fault) { TraceInvalidEvent(e, false); TryToAbortTransaction(e, enlistment); } void InvalidParticipantFaultEvent(SynchronizationEvent e, ParticipantEnlistment participant) { TraceInvalidEvent(e, false); TryToAbortTransaction(e, participant); } void InvalidSendMessageFailureEvent(SynchronizationEvent e, TransactionEnlistment enlistment) { TraceInvalidEvent(e, false); TryToAbortTransaction(e, enlistment); } void InvalidTimerEvent(SynchronizationEvent e) { TraceInvalidEvent(e, true); InvalidEventFailfast (e); } void InvalidInternalEvent(SynchronizationEvent e) { TraceInvalidEvent(e, true); InvalidEventFailfast(e); } // // Shared invalid event handling // protected void TraceInvalidEvent(SynchronizationEvent e, bool fatal) { // The state machine does the dirty work of handling this e.StateMachine.TraceInvalidEvent(e, fatal); } protected void TrySendAborted(CoordinatorEnlistment coordinator) { if (coordinator.CoordinatorProxy != null) { state.TwoPhaseCommitParticipant.SendDurableAborted(coordinator); } } protected void TrySendAborted(VolatileCoordinatorEnlistment coordinator) { if (coordinator.CoordinatorProxy != null) { state.TwoPhaseCommitParticipant.SendVolatileAborted(coordinator); } } protected void TrySendFault(DurableTwoPhaseCommitCoordinatorEvent e, Fault fault) { state.TwoPhaseCommitParticipant.SendFault(e.FaultTo, e.MessageId, fault); } protected void TrySendFault(VolatileTwoPhaseCommitCoordinatorEvent e, Fault fault) { state.TwoPhaseCommitParticipant.SendFault(e.FaultTo, e.MessageId, fault); } void TryToAbortTransaction(SynchronizationEvent e, TransactionEnlistment enlistment) { // Decide what to do, given our state type // Yes, we should use inheritance for this, but it's good to have all the code in one place if (this is InactiveState) { // This always means that we don't have an enlistment yet, but we may in the future // Transition to the aborted state, which will handle aborting if we get an enlistment enlistment.StateMachine.ChangeState(enlistment.StateMachine.AbortedState); } else if (this is ActiveState) { // Abort the local transaction state.TransactionManagerSend.Rollback(enlistment); // Transition to the aborted state enlistment.StateMachine.ChangeState(enlistment.StateMachine.AbortedState); } else { // We cannot influence the outcome of the transaction. // Our caller will send a fault if necessary } } //////////////////// // Shared methods // //////////////////// protected void ProcessTmRegisterResponse (TmRegisterResponseEvent e) { ParticipantEnlistment participant = e.Participant; MsgRegisterEvent source = e.SourceEvent; if (e.Status != Status.Success) { // Send a fault back to the registrant Fault fault = this.state.Faults.ParticipantTMRegistrationFailed(e.Status); state.RegistrationCoordinator.SendFault(source.Result, fault); if (RegisterParticipantFailureRecord.ShouldTrace) { RegisterParticipantFailureRecord.Trace( participant.EnlistmentId, participant.Enlistment.RemoteTransactionId, participant.ControlProtocol, participant.ParticipantProxy.To, SR.GetString(SR.PplCreateSubordinateEnlistmentFailed, e.Status.ToString()), this.state.ProtocolVersion ); } // It is worth noting that we don't rollback the transaction at this point // This matches behavior elsewhere in the protocol where we don't rollback // when a new participant can't be registered. } else { participant.OnParticipantRegistered(); // Send success response state.RegistrationCoordinator.SendRegisterResponse(participant, source.Result, source.Protocol, participant.CoordinatorService); if (RegisterParticipantRecord.ShouldTrace) { RegisterParticipantRecord.Trace ( participant.EnlistmentId, participant.Enlistment.RemoteTransactionId, participant.ControlProtocol, participant.ParticipantProxy.To, this.state.ProtocolVersion ); } } } protected void ProcessTmAsyncRollback(TmAsyncRollbackEvent e) { CoordinatorEnlistment coordinator = (CoordinatorEnlistment)e.Enlistment; // Tell the TM we aborted coordinator.SetCallback(e.Callback, e.CallbackState); state.TransactionManagerSend.Aborted(coordinator); e.StateMachine.ChangeState(state.States.CoordinatorAborted); } protected void SetDurableCoordinatorActive(MsgRegisterDurableResponseEvent e) { CoordinatorEnlistment coordinator = e.Coordinator; coordinator.SetCoordinatorProxy(e.Proxy); coordinator.OnDurableCoordinatorActive(); if (RegisterCoordinatorRecord.ShouldTrace) { RegisterCoordinatorRecord.Trace( coordinator.EnlistmentId, coordinator.SuperiorContext, ControlProtocol.Durable2PC, e.Proxy.To, this.state.ProtocolVersion ); } } protected void EnlistPrePrepare(TmEnlistPrePrepareEvent e) { CoordinatorEnlistment coordinator = e.Coordinator; coordinator.OnEnlistPrePrepare(e); // Ask our superior for a volatile pipe state.RegistrationParticipant.SendVolatileRegister(coordinator.RegisterVolatileCoordinator); } // We received a CCC w/ context and found nothing in the context lookup table // We tried to be superior to DTC. // DTC told us that it already knew about the transaction. // We're going to create a dummy enlistment that is subordinate to DTC, // in order to learn about the transaction and send a context back protected void ForwardEnlistmentEventToSubordinate(MsgEnlistTransactionEvent e) { CoordinatorEnlistment coordinator = e.Coordinator; // Give up ownership of the context manager TransactionContextManager contextManager = coordinator.ContextManager; coordinator.ContextManager = null; ParticipantEnlistment participant = new ParticipantEnlistment(state, coordinator.Enlistment, contextManager); participant.StateMachine.Enqueue(new InternalEnlistSubordinateTransactionEvent(participant, e)); } // We use the Query* functions for the average elapsed time // counters. public static long QueryStartTime() { return State.QueryTime(-1); } public static long QueryStopTime() { return State.QueryTime(0); } static long QueryTime(long failureDefault) { long retval = 0; if (0 == System.ServiceModel.Channels.UnsafeNativeMethods.QueryPerformanceCounter(out retval)) { retval = failureDefault; } return retval; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- WebControl.cs
- MatrixTransform.cs
- SplitterEvent.cs
- RelatedEnd.cs
- BinaryUtilClasses.cs
- DataListItem.cs
- MarginsConverter.cs
- Border.cs
- SoapRpcServiceAttribute.cs
- SelectionChangedEventArgs.cs
- UserControlBuildProvider.cs
- FillBehavior.cs
- OleDbInfoMessageEvent.cs
- XPathArrayIterator.cs
- ReadOnlyTernaryTree.cs
- TableCell.cs
- Journaling.cs
- SafeLibraryHandle.cs
- XmlNodeReader.cs
- DropSource.cs
- EllipseGeometry.cs
- SqlConnectionStringBuilder.cs
- RightsController.cs
- Deflater.cs
- PathGeometry.cs
- EntityDataSourceStatementEditor.cs
- ServiceReference.cs
- ObjectStateEntry.cs
- Util.cs
- FileVersion.cs
- TargetParameterCountException.cs
- XmlSchemaAttributeGroup.cs
- TextTreeExtractElementUndoUnit.cs
- KeyInfo.cs
- XmlWriterSettings.cs
- PseudoWebRequest.cs
- EventLogger.cs
- EventLogger.cs
- SQLConvert.cs
- precedingsibling.cs
- SchemaMapping.cs
- MobileTextWriter.cs
- PropertyInfoSet.cs
- CodeAttributeDeclaration.cs
- PrintingPermission.cs
- TableItemPattern.cs
- HttpCacheVary.cs
- Decorator.cs
- NavigationProperty.cs
- ObjectListComponentEditor.cs
- NetworkCredential.cs
- Int64AnimationUsingKeyFrames.cs
- DigestTraceRecordHelper.cs
- TcpConnectionPoolSettingsElement.cs
- PointCollectionValueSerializer.cs
- SmtpTransport.cs
- SoapEnumAttribute.cs
- RightsController.cs
- TextChange.cs
- OleDbConnectionPoolGroupProviderInfo.cs
- ImpersonateTokenRef.cs
- ListViewItem.cs
- RemotingConfigParser.cs
- InkSerializer.cs
- FixedStringLookup.cs
- TypeContext.cs
- DateTimeSerializationSection.cs
- OdbcException.cs
- HandleCollector.cs
- XslCompiledTransform.cs
- ArrangedElement.cs
- cache.cs
- RuntimeIdentifierPropertyAttribute.cs
- AutoCompleteStringCollection.cs
- InputBinder.cs
- WmfPlaceableFileHeader.cs
- HotCommands.cs
- RenderingBiasValidation.cs
- TrustManagerPromptUI.cs
- TextServicesHost.cs
- DataTableMappingCollection.cs
- RunInstallerAttribute.cs
- cookieexception.cs
- ModuleConfigurationInfo.cs
- DependencyPropertyKind.cs
- UTF8Encoding.cs
- MethodSet.cs
- Timeline.cs
- DbMetaDataColumnNames.cs
- FileLevelControlBuilderAttribute.cs
- StateMachine.cs
- FormClosingEvent.cs
- SoapExtensionReflector.cs
- WebPartEditorCancelVerb.cs
- EditorZone.cs
- RegexCode.cs
- DeferredReference.cs
- RegionInfo.cs
- DLinqTableProvider.cs
- FormatVersion.cs