Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / TransactionBridge / Microsoft / Transactions / Wsat / StateMachines / Durable.cs / 1 / Durable.cs
//------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
// This file contains the implementation of the various states used by
// the durable TwoPhaseCommit participant state machine
using System;
using System.Diagnostics;
using System.ServiceModel.Channels;
using Microsoft.Transactions.Bridge;
using Microsoft.Transactions.Wsat.InputOutput;
using Microsoft.Transactions.Wsat.Messaging;
using Microsoft.Transactions.Wsat.Protocol;
using Microsoft.Transactions.Wsat.Recovery;
using DiagnosticUtility = Microsoft.Transactions.Bridge.DiagnosticUtility;
namespace Microsoft.Transactions.Wsat.StateMachines
{
//=============================================================================
// DurableRegistering
//
// A participant registered for durable 2PC
// We asked the TM to create a new subordinate enlistment
//=============================================================================
class DurableRegistering : InactiveState
{
public DurableRegistering (ProtocolState state) : base (state) {}
public override void OnEvent(TmRegisterResponseEvent e)
{
ProcessTmRegisterResponse(e);
if (e.Status == Status.Success)
{
e.StateMachine.ChangeState(state.States.DurableActive);
}
else
{
e.StateMachine.ChangeState(state.States.DurableInitializationFailed);
}
}
}
//==============================================================================
// DurableActive
//
// The TM created a subordinate enlistment and success was sent to the registrant
//=============================================================================
class DurableActive : ActiveState
{
public DurableActive (ProtocolState state) : base (state) {}
// Unsolicited ReadOnly
public override void OnEvent(MsgReadOnlyEvent e)
{
e.StateMachine.ChangeState(state.States.DurableUnregistered);
}
// Unsolicited Aborted
public override void OnEvent(MsgAbortedEvent e)
{
state.TransactionManagerSend.Rollback (e.Participant);
e.StateMachine.ChangeState(state.States.DurableAborted);
}
// The WS-AT 1.0 state machines dictate a polite answer for Replay
// System.Transactions allows a durable participant to receive a phase zero prepare
// instead of a phase one prepare. This implies that it might attempt to recover while
// the coordinator is still active, since System.Transactions will register a volatile
// for the phase zero prepare.
//
// We wouldnt want the participant to receive a fault when it should really
// receive a polite Rollback message.
public override void OnEvent(MsgReplayEvent e)
{
ProtocolVersionHelper.AssertProtocolVersion10(this.state.ProtocolVersion, typeof(DurableActive), "OnEvent(replay)");
ParticipantEnlistment participant = e.Participant;
state.TwoPhaseCommitCoordinator.SendRollback (participant);
state.TransactionManagerSend.Rollback (participant);
e.StateMachine.ChangeState(state.States.DurableAborted);
}
public override void OnEvent(TmPrepareEvent e)
{
ParticipantEnlistment participant = e.Participant;
participant.SetCallback(e.Callback, e.CallbackState);
state.TwoPhaseCommitCoordinator.SendPrepare (participant);
e.StateMachine.ChangeState(state.States.DurablePreparing);
}
public override void OnEvent(TmRollbackEvent e)
{
ParticipantEnlistment participant = e.Participant;
state.TwoPhaseCommitCoordinator.SendRollback (participant);
participant.SetCallback(e.Callback, e.CallbackState);
state.TransactionManagerSend.Aborted(participant);
e.StateMachine.ChangeState(state.States.DurableAborted);
}
}
//==============================================================================
// DurableUnregistered
//
// The participant sent an unsolicited readonly and "unregistered" from the transaction
// This is an active state because we can still abort
//==============================================================================
class DurableUnregistered : ActiveState
{
public DurableUnregistered (ProtocolState state) : base (state) {}
// Tolerate duplicate messages
public override void OnEvent(MsgReadOnlyEvent e)
{
return;
}
// Deliver the ReadOnly we're been saving up
public override void OnEvent(TmPrepareEvent e)
{
ParticipantEnlistment participant = e.Participant;
participant.SetCallback(e.Callback, e.CallbackState);
state.TransactionManagerSend.ReadOnly (participant);
e.StateMachine.ChangeState(state.States.DurableInDoubt);
}
public override void OnEvent(TmRollbackEvent e)
{
ParticipantEnlistment participant = e.Participant;
participant.SetCallback(e.Callback, e.CallbackState);
state.TransactionManagerSend.Aborted(participant);
e.StateMachine.ChangeState(state.States.DurableAborted);
}
}
//=============================================================================
// DurablePreparing
//
// The TM told us to prepare. We told the participant to prepare
//==============================================================================
class DurablePreparing : ActiveState
{
public DurablePreparing (ProtocolState state) : base (state) {}
public override void Enter (StateMachine stateMachine)
{
base.Enter (stateMachine);
// Set send Prepare time for performance counter
((ParticipantEnlistment)stateMachine.Enlistment).LastMessageTime = State.QueryStartTime();
// Start up a Prepare timer
stateMachine.StartTimer (TimerProfile.Preparing);
}
public override void Leave (StateMachine stateMachine)
{
base.Leave (stateMachine);
ParticipantEnlistment participant = (ParticipantEnlistment) stateMachine.Enlistment;
long elapsed = State.QueryStopTime() - participant.LastMessageTime;
state.Perf.AverageParticipantPrepareResponseTimeBase.Increment();
state.Perf.AverageParticipantPrepareResponseTime.IncrementBy(elapsed);
// Cancel the Prepare timer
participant.Retries = 0;
stateMachine.CancelTimer();
}
public override void OnEvent(MsgReadOnlyEvent e)
{
state.TransactionManagerSend.ReadOnly (e.Participant);
e.StateMachine.ChangeState(state.States.DurableInDoubt);
}
public override void OnEvent(MsgPreparedEvent e)
{
ParticipantEnlistment participant = e.Participant;
Exception failed = null;
try
{
byte[] recovery = state.LogEntrySerialization.Serialize(participant);
participant.Enlistment.SetRecoveryData (recovery);
state.TransactionManagerSend.Prepared (participant);
e.StateMachine.ChangeState(state.States.DurablePrepared);
}
catch (SerializationException exception)
{
DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Error);
failed = exception;
}
if (failed != null)
{
if (DebugTrace.Error)
DebugTrace.Trace(TraceLevel.Verbose,
"Failed to serialize log entry for participant: {0}",
failed);
ParticipantRecoveryLogEntryCreationFailureRecord.TraceAndLog(
participant.EnlistmentId,
participant.Enlistment.RemoteTransactionId,
failed.Message,
failed
);
// We react to serialization failures by aborting the transaction
state.TwoPhaseCommitCoordinator.SendRollback (participant);
state.TransactionManagerSend.Aborted(participant);
e.StateMachine.ChangeState(state.States.DurableAborted);
}
}
public override void OnEvent(MsgAbortedEvent e)
{
state.TransactionManagerSend.Aborted(e.Participant);
e.StateMachine.ChangeState(state.States.DurableAborted);
}
// We might also receive a Replay in this state, but we're going to call that a failure
//
// We abort the transaction if this occurs. We never received a Prepared message
// from this participant, and we don't really know what could have happened to it.
// There are cases where the participant might write a Prepared log record, then
// try to send Prepared, fail, decide to abort and fail. An RM would generally write
// an abort log record before performing undo steps, but a TM can optimize the log write
// by neglecting to write an abort record and simply forgetting its local state. If the TM
// were to fail after, say, having sent rollbacks to half of its participants, it would wake
// up in an indoubt state with respect to that transaction.
//
// In these cases, the participant relies on us to keep it straight.
//
// The sad thing is that there are legitimate cases where this pattern could occur. If the
// participant's Prepared response were lost and then the participant failed, we would
// see this message in this state. Unfortunately, we can't tell the difference between
// a legitimate replay and the case described above.
public override void OnEvent(MsgReplayEvent e)
{
ProtocolVersionHelper.AssertProtocolVersion10(this.state.ProtocolVersion, typeof(DurablePreparing), "OnEvent(replay)");
ParticipantEnlistment participant = e.Participant;
if (DurableParticipantReplayWhilePreparingRecord.ShouldTrace)
{
DurableParticipantReplayWhilePreparingRecord.Trace (
participant.EnlistmentId,
participant.Enlistment.RemoteTransactionId
);
}
state.TwoPhaseCommitCoordinator.SendRollback (participant);
state.TransactionManagerSend.Aborted(participant);
e.StateMachine.ChangeState(state.States.DurableAborted);
}
// Async rollback from the TM... Could be a timeout, could be another participant aborting
public override void OnEvent(TmRollbackEvent e)
{
ParticipantEnlistment participant = e.Participant;
state.TwoPhaseCommitCoordinator.SendRollback (participant);
participant.SetCallback(e.Callback, e.CallbackState);
state.TransactionManagerSend.Aborted(participant);
e.StateMachine.ChangeState(state.States.DurableAborted);
}
public override void OnEvent(TimerParticipantEvent e)
{
ParticipantEnlistment participant = e.Participant;
participant.Retries ++;
if (PrepareMessageRetryRecord.ShouldTrace)
{
PrepareMessageRetryRecord.Trace (
participant.EnlistmentId,
participant.Enlistment.RemoteTransactionId,
participant.Retries
);
}
state.Perf.PrepareRetryCountPerInterval.Increment();
// Send another prepare message
state.TwoPhaseCommitCoordinator.SendPrepare (participant);
}
}
//=============================================================================
// DurablePrepared
//
// The participant said prepared. We told the TM prepared
//=============================================================================
class DurablePrepared : DecidedState
{
public DurablePrepared (ProtocolState state) : base (state) {}
// Tolerate duplicate messages
public override void OnEvent(MsgPreparedEvent e)
{
return;
}
// We will deliver outcome when we're ready
public override void OnEvent(MsgReplayEvent e)
{
ProtocolVersionHelper.AssertProtocolVersion10(this.state.ProtocolVersion, typeof(DurablePrepared), "OnEvent(replay)");
return;
}
public override void OnEvent(TmCommitEvent e)
{
ParticipantEnlistment participant = e.Participant;
state.TwoPhaseCommitCoordinator.SendCommit (participant);
participant.SetCallback(e.Callback, e.CallbackState);
e.StateMachine.ChangeState(state.States.DurableCommitting);
}
public override void OnEvent(TmRollbackEvent e)
{
ParticipantEnlistment participant = e.Participant;
state.TwoPhaseCommitCoordinator.SendRollback (participant);
participant.SetCallback(e.Callback, e.CallbackState);
state.TransactionManagerSend.Aborted(participant);
e.StateMachine.ChangeState(state.States.DurableAborted);
}
public override void OnEvent(TimerParticipantEvent e)
{
return;
}
}
//=============================================================================
// DurableCommitting
//
// The participant has been instructed to commit
//==============================================================================
class DurableCommitting : DecidedState
{
public DurableCommitting (ProtocolState state) : base (state) {}
public override void Enter (StateMachine stateMachine)
{
base.Enter (stateMachine);
// Set send Commit time for performance counter
((ParticipantEnlistment) stateMachine.Enlistment).LastMessageTime = State.QueryStartTime();
// Start up a Commit timer
stateMachine.StartTimer (TimerProfile.Committing);
}
public override void Leave (StateMachine stateMachine)
{
base.Leave (stateMachine);
long elapsed =
State.QueryStopTime() - ((ParticipantEnlistment)stateMachine.Enlistment).LastMessageTime;
state.Perf.AverageParticipantCommitResponseTimeBase.Increment();
state.Perf.AverageParticipantCommitResponseTime.IncrementBy(elapsed);
// Cancel the Commit timer
stateMachine.CancelTimer();
}
// Tolerate duplicate messages
public override void OnEvent(MsgPreparedEvent e)
{
state.TwoPhaseCommitCoordinator.SendCommit (e.Participant);
}
public override void OnEvent(MsgReplayEvent e)
{
ProtocolVersionHelper.AssertProtocolVersion10(this.state.ProtocolVersion, typeof(DurableCommitting), "OnEvent(replay)");
state.TwoPhaseCommitCoordinator.SendCommit (e.Participant);
}
public override void OnEvent(MsgCommittedEvent e)
{
state.TransactionManagerSend.Committed (e.Participant);
e.StateMachine.ChangeState(state.States.DurableCommitted);
}
public override void OnEvent(TmParticipantForgetEvent e)
{
ParticipantEnlistment participant = e.Participant;
participant.SetCallback(e.Callback, e.CallbackState);
state.TransactionManagerSend.ForgetResponse(participant, Status.Success);
e.StateMachine.ChangeState(state.States.DurableInDoubt);
}
public override void OnEvent(TimerParticipantEvent e)
{
// This reminder be from a preparing timer, in which case we'll ignore it
if (e.Profile == TimerProfile.Committing)
{
ParticipantEnlistment participant = e.Participant;
participant.Retries ++;
if (CommitMessageRetryRecord.ShouldTrace)
{
CommitMessageRetryRecord.Trace (
participant.EnlistmentId,
participant.Enlistment.RemoteTransactionId,
participant.Retries
);
}
state.Perf.CommitRetryCountPerInterval.Increment();
// Resend the commit
state.TwoPhaseCommitCoordinator.SendCommit (participant);
}
}
}
//=============================================================================
// DurableRecovering
//
// During recovery, we received a rejoin message from the TM
//==============================================================================
class DurableRecovering : InactiveState
{
public DurableRecovering (ProtocolState state) : base (state) {}
public override void OnEvent(TmRejoinEvent e)
{
if (!state.Recovering)
{
// Being here outside of recovery is impossible.
// This only safe thing to do is crash so that
// we don't corrupt any transaction state.
DiagnosticUtility.FailFast("Rejoin events should only be delivered during recovery");
}
ParticipantEnlistment participant = e.Participant;
participant.SetCallback(e.Callback, e.CallbackState);
state.TransactionManagerSend.Rejoined (participant);
e.StateMachine.ChangeState(state.States.DurableRejoined);
}
}
//==============================================================================
// DurableRejoined
//
// We finished rejoining and await outcome
// We might receive network messages too
//=============================================================================
class DurableRejoined : DecidedState
{
public DurableRejoined (ProtocolState state) : base (state) {}
// We will deliver outcome when we're ready
public override void OnEvent(MsgPreparedEvent e)
{
return;
}
// We will deliver outcome when we're ready
public override void OnEvent(MsgReplayEvent e)
{
ProtocolVersionHelper.AssertProtocolVersion10(this.state.ProtocolVersion, typeof(DurableRejoined), "OnEvent(replay)");
return;
}
public override void OnEvent(MsgCommittedEvent e)
{
return;
}
public override void OnEvent(MsgAbortedEvent e)
{
return;
}
public override void OnEvent(TmCommitEvent e)
{
// If we're still recovering, put the event in the recovery queue
if (state.Recovering && state.TryEnqueueRecoveryOutcome (e))
{
e.StateMachine.ChangeState(state.States.DurableRecoveryAwaitingCommit);
}
else
{
e.Participant.SetCallback(e.Callback, e.CallbackState);
e.StateMachine.ChangeState(state.States.DurableRecoveryReceivedCommit);
}
}
public override void OnEvent(TmRollbackEvent e)
{
// If we're still recovering, put the event in the recovery queue
if (state.Recovering && state.TryEnqueueRecoveryOutcome (e))
{
e.StateMachine.ChangeState(state.States.DurableRecoveryAwaitingRollback);
}
else
{
e.Participant.SetCallback(e.Callback, e.CallbackState);
e.StateMachine.ChangeState(state.States.DurableRecoveryReceivedRollback);
}
}
}
//==============================================================================
// DurableRecoveryAwaitingCommit
//
// We enqueued a commit outcome from the TM in the recovery queue
//=============================================================================
class DurableRecoveryAwaitingCommit : DecidedState
{
public DurableRecoveryAwaitingCommit (ProtocolState state) : base (state) {}
// We will deliver outcome when we're ready
public override void OnEvent(MsgPreparedEvent e)
{
return;
}
// We will deliver outcome when we're ready
public override void OnEvent(MsgReplayEvent e)
{
ProtocolVersionHelper.AssertProtocolVersion10(this.state.ProtocolVersion, typeof(DurableRecoveryAwaitingCommit), "OnEvent(replay)");
return;
}
public override void OnEvent(MsgCommittedEvent e)
{
// We must have sent a commit to the participant in a previous life
e.StateMachine.ChangeState(state.States.DurableCommitted);
}
// This is a repost sent when recovery ended
public override void OnEvent(TmCommitEvent e)
{
if (state.Recovering)
{
// Being here inside of recovery is impossible.
// This only safe thing to do is crash so that
// we don't corrupt any transaction state.
DiagnosticUtility.FailFast("Rejoin events should only be re-delivered after recovery");
}
e.Participant.SetCallback(e.Callback, e.CallbackState);
e.StateMachine.ChangeState(state.States.DurableRecoveryReceivedCommit);
}
public override void OnEvent(TmParticipantForgetEvent e)
{
ParticipantEnlistment participant = e.Participant;
participant.SetCallback(e.Callback, e.CallbackState);
state.TransactionManagerSend.ForgetResponse(participant, Status.Success);
e.StateMachine.ChangeState(state.States.DurableInDoubt);
}
}
//=============================================================================
// DurableRecoveryReceivedCommit
//
// We recovered a participant enlistment, and the TM told us to commit
//=============================================================================
class DurableRecoveryReceivedCommit : DecidedState
{
public DurableRecoveryReceivedCommit(ProtocolState state) : base(state) {}
public override void Enter(StateMachine stateMachine)
{
ParticipantEnlistment participant = (ParticipantEnlistment) stateMachine.Enlistment;
// Ensure our proxy has a proper 'from'
participant.CreateCoordinatorService();
// Send our participant a commit
state.TwoPhaseCommitCoordinator.SendCommit(participant);
// We'll ack the TM later, when the participant responds
stateMachine.ChangeState(state.States.DurableCommitting);
}
}
//==============================================================================
// DurableRecoveryAwaitingRollback
//
// We enqueued a rollback outcome from the TM in the recovery queue
//=============================================================================
class DurableRecoveryAwaitingRollback : DecidedState
{
public DurableRecoveryAwaitingRollback (ProtocolState state) : base (state) {}
// We will deliver outcome when we're ready
public override void OnEvent(MsgPreparedEvent e)
{
return;
}
// We'll deliver outcome when we receive our TmRollbackEvent repost
public override void OnEvent(MsgReplayEvent e)
{
ProtocolVersionHelper.AssertProtocolVersion10(this.state.ProtocolVersion, typeof(DurableRecoveryAwaitingRollback), "OnEvent(replay)");
return;
}
// We must have sent a rollback to the participant in a previous life
public override void OnEvent(MsgAbortedEvent e)
{
e.StateMachine.ChangeState(state.States.DurableAborted);
}
// This is a repost sent when recovery ended
public override void OnEvent(TmRollbackEvent e)
{
e.Participant.SetCallback(e.Callback, e.CallbackState);
e.StateMachine.ChangeState(state.States.DurableRecoveryReceivedRollback);
}
}
//==============================================================================
// DurableRecoveryReceivedRollback
//
// We recovered a participant enlistment, and the TM told us to rollback
//==============================================================================
class DurableRecoveryReceivedRollback : DecidedState
{
public DurableRecoveryReceivedRollback(ProtocolState state) : base(state) {}
public override void Enter(StateMachine stateMachine)
{
ParticipantEnlistment participant = (ParticipantEnlistment) stateMachine.Enlistment;
// Ensure our proxy has a proper 'from'
participant.CreateCoordinatorService();
// Send our participant a rollback
state.TwoPhaseCommitCoordinator.SendRollback (participant);
// Ack the TM
state.TransactionManagerSend.Aborted(participant);
stateMachine.ChangeState(state.States.DurableAborted);
}
}
//=============================================================================
// DurableFailedRecovery
//
// We failed to create a proxy during recovery, so we sit idle and wait
// On restart, perhaps we will have better luck with policy negotiation
//==============================================================================
class DurableFailedRecovery : DecidedState
{
public DurableFailedRecovery (ProtocolState state) : base (state) {}
public override void OnEvent(TmRejoinEvent e)
{
ParticipantEnlistment participant = e.Participant;
participant.SetCallback(e.Callback, e.CallbackState);
state.TransactionManagerSend.Rejoined(participant);
}
public override void OnEvent(TmCommitEvent e)
{
return;
}
public override void OnEvent(TmRollbackEvent e)
{
ParticipantEnlistment participant = e.Participant;
participant.SetCallback(e.Callback, e.CallbackState);
state.TransactionManagerSend.Aborted(participant);
e.StateMachine.ChangeState(state.States.DurableAborted);
}
public override void OnEvent(TmParticipantForgetEvent e)
{
ParticipantEnlistment participant = e.Participant;
participant.SetCallback(e.Callback, e.CallbackState);
state.TransactionManagerSend.ForgetResponse(participant, Status.Success);
e.StateMachine.ChangeState(state.States.DurableInDoubt);
}
}
//=============================================================================
// DurableCommitted
//
// We think we're done, and the transaction committed
//=============================================================================
class DurableCommitted : TerminalState
{
public DurableCommitted (ProtocolState state) : base (state) {}
public override void Enter (StateMachine stateMachine)
{
base.Enter (stateMachine);
if (ParticipantStateMachineFinishedRecord.ShouldTrace)
{
ParticipantStateMachineFinishedRecord.Trace(
stateMachine.Enlistment.EnlistmentId,
stateMachine.Enlistment.Enlistment.RemoteTransactionId,
TransactionOutcome.Committed
);
}
}
// We already received a committed message
public override void OnEvent(MsgPreparedEvent e)
{
return;
}
public override void OnEvent(MsgCommittedEvent e)
{
return;
}
// We already received a committed message
public override void OnEvent(MsgReplayEvent e)
{
ProtocolVersionHelper.AssertProtocolVersion10(this.state.ProtocolVersion, typeof(DurableCommitted), "OnEvent(replay)");
return;
}
// This is a repost from the recovery queue
public override void OnEvent(TmCommitEvent e)
{
ParticipantEnlistment participant = e.Participant;
participant.SetCallback(e.Callback, e.CallbackState);
state.TransactionManagerSend.Committed (participant);
}
public override void OnEvent(TmParticipantForgetEvent e)
{
ParticipantEnlistment participant = e.Participant;
participant.SetCallback(e.Callback, e.CallbackState);
state.TransactionManagerSend.ForgetResponse(participant, Status.Success);
}
public override void OnEvent(TimerParticipantEvent e)
{
return;
}
}
//=============================================================================
// DurableAborted
//
// We think we're done, and the transaction aborted
//==============================================================================
class DurableAborted : TerminalState
{
public DurableAborted(ProtocolState state) : base (state) {}
public override void Enter (StateMachine stateMachine)
{
base.Enter (stateMachine);
if (ParticipantStateMachineFinishedRecord.ShouldTrace)
{
ParticipantStateMachineFinishedRecord.Trace(
stateMachine.Enlistment.EnlistmentId,
stateMachine.Enlistment.Enlistment.RemoteTransactionId,
TransactionOutcome.Aborted
);
}
}
public override void OnEvent(MsgReadOnlyEvent e)
{
return;
}
public override void OnEvent(MsgPreparedEvent e)
{
state.TwoPhaseCommitCoordinator.SendRollback(e.ReplyTo);
}
public override void OnEvent(MsgAbortedEvent e)
{
return;
}
public override void OnEvent(MsgReplayEvent e)
{
ProtocolVersionHelper.AssertProtocolVersion10(this.state.ProtocolVersion, typeof(DurableAborted), "OnEvent(replay)");
state.TwoPhaseCommitCoordinator.SendRollback(e.ReplyTo);
}
public override void OnEvent(TmPrepareEvent e)
{
ParticipantEnlistment participant = e.Participant;
participant.SetCallback(e.Callback, e.CallbackState);
state.TransactionManagerSend.Aborted(participant);
}
public override void OnEvent(TmRollbackEvent e)
{
ParticipantEnlistment participant = e.Participant;
participant.SetCallback(e.Callback, e.CallbackState);
state.TransactionManagerSend.Aborted(participant);
}
public override void OnEvent(TmRollbackResponseEvent e)
{
if (e.Status != Status.Aborted)
{
// The only valid status is Aborted. If this is not true, we
// shouldn't be in this state method.
DiagnosticUtility.FailFast("Transaction manager should respond Aborted to Rollback");
}
return;
}
public override void OnEvent(TmParticipantForgetEvent e)
{
ParticipantEnlistment participant = e.Participant;
participant.SetCallback(e.Callback, e.CallbackState);
state.TransactionManagerSend.ForgetResponse(participant, Status.Success);
}
public override void OnEvent(TimerParticipantEvent e)
{
return;
}
}
//=============================================================================
// DurableInDoubt
//
// We think we're done, and the transaction is indoubt
//==============================================================================
class DurableInDoubt : TerminalState
{
public DurableInDoubt (ProtocolState state) : base (state) {}
public override void Enter (StateMachine stateMachine)
{
base.Enter (stateMachine);
if (ParticipantStateMachineFinishedRecord.ShouldTrace)
{
ParticipantStateMachineFinishedRecord.Trace(
stateMachine.Enlistment.EnlistmentId,
stateMachine.Enlistment.Enlistment.RemoteTransactionId,
TransactionOutcome.InDoubt
);
}
}
public override void OnEvent(MsgReadOnlyEvent e)
{
return;
}
public override void OnEvent(MsgAbortedEvent e)
{
return;
}
public override void OnEvent(MsgCommittedEvent e)
{
return;
}
public override void OnEvent(TmRollbackEvent e)
{
ParticipantEnlistment participant = e.Participant;
participant.SetCallback(e.Callback, e.CallbackState);
state.TransactionManagerSend.Aborted(participant);
}
public override void OnEvent(TimerParticipantEvent e)
{
return;
}
}
//==============================================================================
// DurableInitializationFailed
//
// We think we're done because we couldn't create a subordinate enlistment
//=============================================================================
class DurableInitializationFailed : TerminalState
{
public DurableInitializationFailed(ProtocolState state) : base(state) { }
}
}
// 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
- TextUtf8RawTextWriter.cs
- WindowsRegion.cs
- AttributeProviderAttribute.cs
- DecoratedNameAttribute.cs
- ColorAnimationBase.cs
- XmlUtilWriter.cs
- StringValueSerializer.cs
- EncodingTable.cs
- ThicknessAnimation.cs
- CommandManager.cs
- InputBinding.cs
- IdleTimeoutMonitor.cs
- SetStateEventArgs.cs
- CompiledQuery.cs
- ParseChildrenAsPropertiesAttribute.cs
- BamlWriter.cs
- XmlDataSource.cs
- Resources.Designer.cs
- SqlDesignerDataSourceView.cs
- ButtonFieldBase.cs
- BasicViewGenerator.cs
- MenuEventArgs.cs
- GridViewCommandEventArgs.cs
- MessageUtil.cs
- EntityDataSourceEntityTypeFilterConverter.cs
- RenderingBiasValidation.cs
- DBSchemaRow.cs
- TextRangeAdaptor.cs
- InputLangChangeEvent.cs
- PropertiesTab.cs
- ColumnMapCopier.cs
- CompiledELinqQueryState.cs
- Brush.cs
- WebWorkflowRole.cs
- SelectionPatternIdentifiers.cs
- VsPropertyGrid.cs
- isolationinterop.cs
- PlacementWorkspace.cs
- CryptographicAttribute.cs
- SqlMethodTransformer.cs
- Hex.cs
- JapaneseLunisolarCalendar.cs
- TypeDelegator.cs
- InlinedAggregationOperator.cs
- CodeSubDirectory.cs
- PerspectiveCamera.cs
- HierarchicalDataTemplate.cs
- LocatorManager.cs
- MsmqMessage.cs
- TaskForm.cs
- EnumerableRowCollectionExtensions.cs
- DbParameterHelper.cs
- SafeHandles.cs
- ClientProxyGenerator.cs
- ObjectNavigationPropertyMapping.cs
- CompositeActivityMarkupSerializer.cs
- ReferenceTypeElement.cs
- WindowsScrollBar.cs
- DataBindingCollection.cs
- AsymmetricSignatureFormatter.cs
- TextPointerBase.cs
- EditorPartCollection.cs
- SrgsToken.cs
- WebPartUserCapability.cs
- LicenseException.cs
- DataTemplate.cs
- ContractNamespaceAttribute.cs
- ActiveXContainer.cs
- MatrixAnimationUsingPath.cs
- PiiTraceSource.cs
- ProfileBuildProvider.cs
- securitycriticaldataformultiplegetandset.cs
- SafeNativeMethods.cs
- XmlTextReaderImplHelpers.cs
- DataGridViewUtilities.cs
- PasswordRecovery.cs
- WindowsAltTab.cs
- MaskedTextBoxTextEditor.cs
- MdImport.cs
- TextSegment.cs
- Empty.cs
- X509Extension.cs
- SizeConverter.cs
- ListViewTableCell.cs
- ToolbarAUtomationPeer.cs
- Processor.cs
- OrderedEnumerableRowCollection.cs
- CurrentTimeZone.cs
- TextDecorationCollection.cs
- DefaultPrintController.cs
- PropertyItem.cs
- TextElementCollectionHelper.cs
- TypeGenericEnumerableViewSchema.cs
- NamespaceListProperty.cs
- RemoveStoryboard.cs
- TextEndOfSegment.cs
- ReadOnlyNameValueCollection.cs
- LocatorPartList.cs
- SplitterPanel.cs
- ColumnTypeConverter.cs