Completion.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / TransactionBridge / Microsoft / Transactions / Wsat / StateMachines / Completion.cs / 1 / Completion.cs

                            //------------------------------------------------------------------------------ 
// Copyright(c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

// This file contains the the implementations of the various states used by 
// the Completion participant state machine
 
using System; 
using System.Diagnostics;
using System.ServiceModel; 

using Microsoft.Transactions.Bridge;
using Microsoft.Transactions.Wsat.InputOutput;
using Microsoft.Transactions.Wsat.Messaging; 
using Microsoft.Transactions.Wsat.Protocol;
 
using DiagnosticUtility = Microsoft.Transactions.Bridge.DiagnosticUtility; 

namespace Microsoft.Transactions.Wsat.StateMachines 
{
    //=============================================================================
    // CompletionInitializing
    // 
    // A CreateTransaction message was received, and a new transaction
    // object was created to process it. 
    //============================================================================= 
    class CompletionInitializing : InactiveState
    { 
        public CompletionInitializing(ProtocolState state) : base(state) { }

        public override void OnEvent(MsgCreateTransactionEvent e)
        { 
            CompletionEnlistment completion = e.Completion;
 
            EnlistmentOptions options = completion.CreateEnlistmentOptions(e.Body.Expires, 
                                                                           e.Body.ExpiresPresent,
                                                                           e.Body.IsolationLevel, 
                                                                           0,
                                                                           null);

            state.TransactionManagerSend.CreateTransaction (completion, options, e); 
            e.StateMachine.ChangeState(state.States.CompletionCreating);
        } 
    } 

    //============================================================================== 
    // CompletionCreating
    //
    // The TM has been asked to create a new transaction
    //============================================================================= 
    class CompletionCreating : InactiveState
    { 
        public CompletionCreating(ProtocolState state) : base (state) { } 

        public override void OnEvent(TmCreateTransactionResponseEvent e) 
        {
            MsgCreateTransactionEvent source = e.SourceEvent;
            CompletionEnlistment completion = e.Completion;
 
            if (e.Status != Status.Success)
            { 
                // Send a fault to the caller 
                Microsoft.Transactions.Wsat.Messaging.Fault fault = this.state.Faults.CannotCreateContext;
                state.ActivationCoordinator.SendFault(source.Result, fault); 

                if (CreateTransactionFailureRecord.ShouldTrace)
                {
                    CreateTransactionFailureRecord.Trace ( 
                        completion.EnlistmentId,
                        SR.GetString (SR.PplCreateTransactionFailed, e.Status.ToString()) 
                        ); 
                }
 
                completion.StateMachine.ChangeState(state.States.CompletionInitializationFailed);
            }
            else
            { 
                completion.OnRootTransactionCreated();
 
                TransactionContext context = completion.ContextManager.TransactionContext; 
                state.ActivationCoordinator.SendCreateCoordinationContextResponse(context, source.Result);
 
                completion.StateMachine.ChangeState(state.States.CompletionCreated);
            }
        }
    } 

    //============================================================================== 
    // CompletionCreated 
    //
    // The TM successfully created a new transaction, but no one has registered 
    // for completion.
    //==============================================================================
    class CompletionCreated : ActiveState
    { 
        public CompletionCreated(ProtocolState state) : base (state) {}
 
        public override void OnEvent(MsgRegisterCompletionEvent e) 
        {
            CompletionEnlistment completion = e.Completion; 
            completion.SetCompletionProxy(e.Proxy);

            state.RegistrationCoordinator.SendRegisterResponse(completion,
                                                               e.Result, 
                                                               ControlProtocol.Completion,
                                                               completion.CoordinatorService); 
 
            e.StateMachine.ChangeState(state.States.CompletionActive);
        } 

        // The most likely cause of this is a transaction timeout
        public override void OnEvent(TmAsyncRollbackEvent e)
        { 
            CompletionEnlistment completion = (CompletionEnlistment) e.Enlistment;
 
            completion.SetCallback(e.Callback, e.CallbackState); 
            state.TransactionManagerSend.Aborted(completion);
 
            e.StateMachine.ChangeState(state.States.CompletionAborted);
        }
    }
 
    //=============================================================================
    // CompletionActive 
    // 
    // A transaction was successfully created, and a completion participant
    // was successfully added.  We can now be asked to commit or rollback. 
    //==============================================================================
    class CompletionActive : ActiveState
    {
        public CompletionActive(ProtocolState state) : base (state) {} 

        public override void Enter (StateMachine stateMachine) 
        { 
            base.Enter (stateMachine);
 
            if (RegisterParticipantRecord.ShouldTrace)
            {
                CompletionEnlistment completion = (CompletionEnlistment) stateMachine.Enlistment;
 
                RegisterParticipantRecord.Trace (
                    completion.EnlistmentId, 
                    completion.Enlistment.RemoteTransactionId, 
                    ControlProtocol.Completion,
                    completion.ParticipantProxy.To, 
                    this.state.ProtocolVersion
                    );
            }
        } 

        public override void OnEvent(MsgRegisterCompletionEvent e) 
        { 
            // Sorry, someone already registered
            if (RegisterParticipantFailureRecord.ShouldTrace) 
            {
                RegisterParticipantFailureRecord.Trace(
                    e.Completion.EnlistmentId,
                    e.Completion.Enlistment.RemoteTransactionId, 
                    ControlProtocol.Completion,
                    e.ParticipantService, 
                    SR.GetString(SR.RegisterCompletionFailureDuplicate), 
                    this.state.ProtocolVersion
                    ); 
            }

            state.RegistrationCoordinator.SendFault(e.Result, this.state.Faults.CompletionAlreadyRegistered);
        } 

        public override void OnEvent(MsgCompletionCommitEvent e) 
        { 
            state.TransactionManagerSend.Commit(e.Completion);
            e.StateMachine.ChangeState(state.States.CompletionCommitting); 
        }

        public override void OnEvent(MsgCompletionRollbackEvent e)
        { 
            state.TransactionManagerSend.Rollback(e.Completion);
            e.StateMachine.ChangeState(state.States.CompletionAborting); 
        } 

        public override void OnEvent(TmAsyncRollbackEvent e) 
        {
            CompletionEnlistment completion = (CompletionEnlistment) e.Enlistment;
            state.CompletionCoordinator.SendAborted(completion);
 
            completion.SetCallback(e.Callback, e.CallbackState);
            state.TransactionManagerSend.Aborted(completion); 
 
            e.StateMachine.ChangeState(state.States.CompletionAborted);
        } 
    }

    //=============================================================================
    // CompletionCommitting 
    //
    // The completion participant called Commit on an active transaction. 
    //============================================================================= 
    class CompletionCommitting : DecidedState
    { 
        public CompletionCommitting(ProtocolState state) : base (state) { }

        // Tolerate duplicate commit message
        // Note that the state machine in the spec recommends a rollback if we're in the 
        // preparing state, but to ignore if we're prepared.  Since we can't tell the
        // difference over here, we'll just let the transaction continue (not that we 
        // have much of a choice...) 
        public override void OnEvent(MsgCompletionCommitEvent e)
        { 
            return;
        }

        public override void OnEvent(TmCompletionCommitResponseEvent e) 
        {
            CompletionEnlistment completion = e.Completion; 
 
            State newState;
            switch (e.Status) 
            {
                case Status.Committed:
                    state.CompletionCoordinator.SendCommitted(completion);
                    newState = state.States.CompletionCommitted; 
                    break;
 
                case Status.Aborted: 
                    state.CompletionCoordinator.SendAborted(completion);
                    newState = state.States.CompletionAborted; 
                    break;

                // We do not worry about Status.InDoubt because we always disable SPC
                // when we're the root of the transaction 

                default: 
                    // An invalid Enum value on this internal code path indicates 
                    // a product bug and violates assumptions about
                    // valid values in MSDTC. 
                    DiagnosticUtility.FailFast("Invalid status code");
                    newState = null;    // Keep the compiler happy
                    break;
            } 

            e.StateMachine.ChangeState(newState); 
        } 

        // Trains crossed in the night... 
        // This means aborted, and the completion participant is waiting for a response
        public override void OnEvent(TmAsyncRollbackEvent e)
        {
            CompletionEnlistment completion = (CompletionEnlistment)e.Enlistment; 

            state.CompletionCoordinator.SendAborted(completion); 
 
            completion.SetCallback(e.Callback, e.CallbackState);
            state.TransactionManagerSend.Aborted(completion); 

            e.StateMachine.ChangeState(state.States.CompletionAborted);
        }
    } 

    //============================================================================= 
    // CompletionAborting 
    //
    // The completion participant called Rollback on an active transaction. 
    //==============================================================================
    class CompletionAborting : DecidedState
    {
        public CompletionAborting(ProtocolState state) : base (state) { } 

        public override void OnEvent(MsgCompletionCommitEvent e) 
        { 
            state.CompletionCoordinator.SendAborted(e.Completion);
        } 

        // Tolerate duplicate rollback message
        public override void OnEvent(MsgCompletionRollbackEvent e)
        { 
            state.CompletionCoordinator.SendAborted(e.Completion);
        } 
 
        public override void OnEvent(TmCompletionRollbackResponseEvent e)
        { 
            if (e.Status != Status.Aborted)
            {
                // The only legal response from the TM to us trying to abort a
                // transaction is Status.Aborted. 
                DiagnosticUtility.FailFast("Transaction manager should respond Aborted to Rollback");
            } 
 
            state.CompletionCoordinator.SendAborted(e.Completion);
            e.StateMachine.ChangeState(state.States.CompletionAborted); 
        }

        // Trains crossed in the night...
        // This means aborted, and the completion participant is waiting for a response 
        public override void OnEvent(TmAsyncRollbackEvent e)
        { 
            CompletionEnlistment completion = (CompletionEnlistment) e.Enlistment; 
            state.CompletionCoordinator.SendAborted(completion);
 
            // Be polite
            completion.SetCallback(e.Callback, e.CallbackState);
            state.TransactionManagerSend.Aborted(completion);
 
            e.StateMachine.ChangeState(state.States.CompletionAborted);
        } 
    } 

    //============================================================================= 
    // CompletionCommitted
    //
    // We think we're done, and the transaction committed
    //============================================================================== 
    class CompletionCommitted : TerminalState
    { 
        public CompletionCommitted(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);
            } 
        }

        public override void OnEvent(MsgCompletionCommitEvent e)
        { 
            state.CompletionCoordinator.SendCommitted(e.ReplyTo);
        } 
    } 

    //============================================================================== 
    // CompletionAborted
    //
    // We think we're done, and the transaction aborted
    //============================================================================= 
    class CompletionAborted : TerminalState
    { 
        public CompletionAborted(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(MsgCompletionCommitEvent e)
        { 
            state.CompletionCoordinator.SendAborted(e.ReplyTo);
        } 
 
        public override void OnEvent(MsgCompletionRollbackEvent e)
        { 
            state.CompletionCoordinator.SendAborted(e.ReplyTo);
        }

        public override void OnEvent(TmCompletionRollbackResponseEvent e) 
        {
            if (e.Status != Status.Aborted) 
            { 
                // The only valid state for the state machine to be in is Aborted.
                // Anything else indicates that we executed an 'impossible' path 
                // and should do the safe thing and not corrupt user data.
                DiagnosticUtility.FailFast("Transaction manager should respond Aborted to Rollback");
            }
            return; 
        }
    } 
 
    //==============================================================================
    // CompletionInitializationFailed 
    //
    // We think we're done because we couldn't create a new transaction
    //=============================================================================
    class CompletionInitializationFailed : TerminalState 
    {
        public CompletionInitializationFailed(ProtocolState state) : base(state) { } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK