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
- UpdateDelegates.Generated.cs
- StrokeSerializer.cs
- PagedDataSource.cs
- BaseTreeIterator.cs
- ProviderConnectionPoint.cs
- CompilationUnit.cs
- PermissionSetTriple.cs
- XmlnsCache.cs
- Command.cs
- FileSystemEventArgs.cs
- MethodCallTranslator.cs
- ColumnReorderedEventArgs.cs
- Cursor.cs
- PeerCollaboration.cs
- InputBuffer.cs
- LongValidatorAttribute.cs
- BypassElementCollection.cs
- ArrangedElementCollection.cs
- StrokeRenderer.cs
- TextDataBindingHandler.cs
- webeventbuffer.cs
- CanonicalFontFamilyReference.cs
- ArrayConverter.cs
- CryptoProvider.cs
- _DigestClient.cs
- PingOptions.cs
- VectorAnimationUsingKeyFrames.cs
- OpCopier.cs
- TypeConverterAttribute.cs
- ChangeProcessor.cs
- TrackingRecord.cs
- RegularExpressionValidator.cs
- ErrorStyle.cs
- InvalidFilterCriteriaException.cs
- WebRequestModuleElement.cs
- TimerExtension.cs
- DivideByZeroException.cs
- TreeViewAutomationPeer.cs
- EmbossBitmapEffect.cs
- SpellerStatusTable.cs
- DragEvent.cs
- XPathNavigator.cs
- SqlNodeTypeOperators.cs
- ListComponentEditorPage.cs
- CodeMemberField.cs
- CardSpaceShim.cs
- TimeSpanOrInfiniteConverter.cs
- InputBindingCollection.cs
- XmlAnyAttributeAttribute.cs
- ActivityXRefConverter.cs
- LaxModeSecurityHeaderElementInferenceEngine.cs
- Token.cs
- EdmProperty.cs
- GeneralTransform3DGroup.cs
- ServiceHttpModule.cs
- RoutedEventArgs.cs
- ListSortDescriptionCollection.cs
- SynchronizationContext.cs
- ChtmlSelectionListAdapter.cs
- WebPartTransformerAttribute.cs
- Dictionary.cs
- DataGridViewRowCollection.cs
- EpmCustomContentSerializer.cs
- AsnEncodedData.cs
- Pts.cs
- VerificationException.cs
- Registry.cs
- HostingEnvironment.cs
- KeyPullup.cs
- SqlWriter.cs
- DataException.cs
- Properties.cs
- BinaryMethodMessage.cs
- UnsafeNativeMethods.cs
- Drawing.cs
- SessionStateItemCollection.cs
- ProcessModelInfo.cs
- TextPenaltyModule.cs
- XNodeValidator.cs
- ScriptingProfileServiceSection.cs
- DesignerCategoryAttribute.cs
- SecurityKeyUsage.cs
- DefaultEventAttribute.cs
- Vector3dCollection.cs
- DocumentViewerBase.cs
- SoapRpcMethodAttribute.cs
- RadioButtonPopupAdapter.cs
- NotImplementedException.cs
- TypeExtension.cs
- ConstantSlot.cs
- XmlCharCheckingReader.cs
- HtmlEmptyTagControlBuilder.cs
- JavaScriptObjectDeserializer.cs
- HtmlAnchor.cs
- Accessible.cs
- SHA256.cs
- IfElseDesigner.xaml.cs
- RtfToken.cs
- ConsumerConnectionPoint.cs
- GridViewRowPresenter.cs