TransactionManager.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 / InputOutput / TransactionManager.cs / 1 / TransactionManager.cs

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

// This file implements the callbacks and entry-points used by the TM bridge 
// to call the WS-AT provider
 
using System; 
using System.Diagnostics;
 
using Microsoft.Transactions.Bridge;

using Microsoft.Transactions.Wsat.Messaging;
using Microsoft.Transactions.Wsat.Protocol; 
using Microsoft.Transactions.Wsat.Recovery;
using Microsoft.Transactions.Wsat.StateMachines; 
 
namespace Microsoft.Transactions.Wsat.InputOutput
{ 
    class TransactionManagerReceive : IProtocolProviderCoordinatorService,
                                      IProtocolProviderPropagationService
    {
        ProtocolState state; 

        public TransactionManagerReceive(ProtocolState state) 
        { 
            this.state = state;
        } 

        //
        // Coordination
        // 

        public void Commit(Enlistment enlistment, ProtocolProviderCallback callback, object obj) 
        { 
            ParticipantEnlistment participant = (ParticipantEnlistment)enlistment.ProtocolProviderContext;
            participant.StateMachine.Enqueue(new TmCommitEvent(participant, callback, obj)); 
        }

        public void Rollback(Enlistment enlistment, ProtocolProviderCallback callback, object obj)
        { 
            //
            // Rollback can be called on any kind of enlistment (completion, coordinator, participant) 
            // 
            ParticipantEnlistment participant = enlistment.ProtocolProviderContext as ParticipantEnlistment;
            if (participant != null) 
            {
                participant.StateMachine.Enqueue(new TmRollbackEvent(participant, callback, obj));
            }
            else 
            {
                TransactionEnlistment txEnlistment = (TransactionEnlistment)enlistment.ProtocolProviderContext; 
                txEnlistment.StateMachine.Enqueue(new TmAsyncRollbackEvent(txEnlistment, callback, obj)); 
            }
        } 

        // An MSDTC bug (Windows OS 1412893) can cause SPC to be sent to a volatile participant
        // that has not requested it. Fortunately, we can work around it by declaring Commit.
        // Other protocols might not be so fortunate. 
        public void SinglePhaseCommit(Enlistment enlistment, ProtocolProviderCallback callback, object obj)
        { 
            ParticipantEnlistment participant = (ParticipantEnlistment)enlistment.ProtocolProviderContext; 
            participant.StateMachine.Enqueue(new TmSinglePhaseCommitEvent(participant, callback, obj));
        } 

        public void Forget(Enlistment enlistment, ProtocolProviderCallback callback, object obj)
        {
            ParticipantEnlistment participant = enlistment.ProtocolProviderContext as ParticipantEnlistment; 
            if (participant != null)
            { 
                participant.StateMachine.Enqueue(new TmParticipantForgetEvent(participant, callback, obj)); 
            }
            else 
            {
                CoordinatorEnlistment coordinator = (CoordinatorEnlistment)enlistment.ProtocolProviderContext;
                coordinator.StateMachine.Enqueue(new TmCoordinatorForgetEvent(coordinator, callback, obj));
            } 
        }
 
        public void Prepare(Enlistment enlistment, ProtocolProviderCallback callback, object obj) 
        {
            ParticipantEnlistment participant = (ParticipantEnlistment)enlistment.ProtocolProviderContext; 
            participant.StateMachine.Enqueue(new TmPrepareEvent(participant, callback, obj));
        }

        public void PrePrepare(Enlistment enlistment, ProtocolProviderCallback callback, object obj) 
        {
            ParticipantEnlistment participant = (ParticipantEnlistment)enlistment.ProtocolProviderContext; 
            participant.StateMachine.Enqueue(new TmPrePrepareEvent(participant, callback, obj)); 
        }
 
        //
        // Propagation
        //
 
        public void Begin(Enlistment enlistment, ProtocolProviderCallback callback, object obj)
        { 
            // We do not implement this operation, so it should never be called 
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
        } 

        public void Pull(Enlistment enlistment, byte[] protocolInformation, ProtocolProviderCallback callback, object obj)
        {
            // We do not implement this operation, so it should never be called 
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
        } 
 
        public void Push(Enlistment enlistment, byte[] protocolInformation, ProtocolProviderCallback callback, object obj)
        { 
            // We do not implement this operation, so it should never be called
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
        }
 
        public void MarshalTransaction(Enlistment enlistment, ProtocolProviderCallback callback, object obj)
        { 
            // We do not implement this operation, so it should never be called 
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
        } 

        public void EnlistPrePrepare(Enlistment enlistment, ProtocolProviderCallback callback, object obj)
        {
            CoordinatorEnlistment coordinator = (CoordinatorEnlistment)enlistment.ProtocolProviderContext; 
            coordinator.StateMachine.Enqueue(new TmEnlistPrePrepareEvent(coordinator, callback, obj));
        } 
 
        public void Rejoin(Enlistment enlistment, ProtocolProviderCallback callback, object obj)
        { 
            DebugTrace.TraceEnter(this, "Rejoin");

            ParticipantEnlistment participant = null;
            try 
            {
                participant = state.LogEntrySerialization.DeserializeParticipant(enlistment); 
            } 
            catch (SerializationException e)
            { 
                DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Critical);

                if (DebugTrace.Error)
                { 
                    DebugTrace.Trace(TraceLevel.Error,
                                     "Failed to deserialize log entry for participant: {0}", e); 
                } 

                ParticipantRecoveryLogEntryCorruptRecord.TraceAndLog( 
                    enlistment.LocalTransactionId,
                    enlistment.RemoteTransactionId,
                    enlistment.GetRecoveryData(),
                    e 
                    );
 
                // If we cannot deserialize a participant log entry, we cannot continue executing. 
                // If that participant were still alive and were to send us a Replay, we would
                // respond politely and inform it that the transaction aborted. However, 
                // this might not be true - the transaction might have indeed committed.
                // Since we don't want to corrupt data, we have to failfast.
                DiagnosticUtility.FailFast("A participant recovery log entry could not " +
                                           "be deserialized. This is a fatal condition."); 
            }
 
            if (ParticipantRecoveredRecord.ShouldTrace) 
            {
                ParticipantRecoveredRecord.Trace( 
                    participant.EnlistmentId,
                    participant.Enlistment.RemoteTransactionId,
                    participant.ParticipantProxy != null ? participant.ParticipantProxy.To : null,
                    this.state.ProtocolVersion 
                    );
            } 
 
            participant.StateMachine.Enqueue(new TmRejoinEvent(participant, callback, obj));
 
            DebugTrace.TraceLeave(this, "Rejoin");
        }

        public void Replay(Enlistment enlistment, ProtocolProviderCallback callback, object obj) 
        {
            DebugTrace.TraceEnter(this, "Replay"); 
 
            CoordinatorEnlistment coordinator = null;
            try 
            {
                coordinator = state.LogEntrySerialization.DeserializeCoordinator(enlistment);
            }
            catch (SerializationException e) 
            {
                DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Critical); 
 
                if (DebugTrace.Error)
                { 
                    DebugTrace.Trace(TraceLevel.Error,
                                     "Failed to deserialize log entry for coordinator: {0}", e);
                }
 
                CoordinatorRecoveryLogEntryCorruptRecord.TraceAndLog(
                    enlistment.LocalTransactionId, 
                    enlistment.RemoteTransactionId, 
                    enlistment.GetRecoveryData(),
                    e 
                    );

                // If we cannot deserialize a coordinator log entry, we cannot continue executing.
                // If that coordinator were still alive and were to send us Commit, we would 
                // respond politely and acknowledge the the outcome with Committed. However,
                // this would be a lie - we might later recover the log entry and send a Replay. 
                // Since we already acked the coordinator's Commit, he might tell us to Rollback. 
                // Since we don't want to corrupt data, we have to failfast.
                DiagnosticUtility.FailFast("A coordinator recovery log entry could not " + 
                                           "be deserialized. This is a fatal condition.");
            }

            if (CoordinatorRecoveredRecord.ShouldTrace) 
            {
                CoordinatorRecoveredRecord.Trace( 
                    coordinator.EnlistmentId, 
                    coordinator.Enlistment.RemoteTransactionId,
                    coordinator.CoordinatorProxy != null ? coordinator.CoordinatorProxy.To : null, 
                    this.state.ProtocolVersion
                    );
            }
 
            coordinator.StateMachine.Enqueue(new TmReplayEvent(coordinator, callback, obj));
 
            DebugTrace.TraceLeave(this, "Replay"); 
        }
 
        public void RecoveryBeginning()
        {
            DebugTrace.TraceEnter(this, "RecoveryBeginning");
            try 
            {
                state.RecoveryBeginning(); 
            } 
            catch (Exception e)
            { 
                DebugTrace.Trace(TraceLevel.Error, "RecoveryBeginning failed: {0}", e);

                ProtocolRecoveryBeginningFailureRecord.TraceAndLog(PluggableProtocol.Id(this.state.ProtocolVersion),
                                                                   PluggableProtocol.Name(this.state.ProtocolVersion), 
                                                                   e);
                throw; 
            } 
            finally
            { 
                DebugTrace.TraceLeave(this, "RecoveryBeginning");
            }
        }
 
        public void RecoveryComplete()
        { 
            DebugTrace.TraceEnter(this, "RecoveryComplete"); 

            try 
            {
                state.RecoveryComplete();

                ProtocolRecoveryCompleteRecord.TraceAndLog(PluggableProtocol.Id(this.state.ProtocolVersion), 
                                                           PluggableProtocol.Name(this.state.ProtocolVersion));
            } 
            catch (Exception e) 
            {
                DebugTrace.Trace(TraceLevel.Error, "RecoveryComplete failed: {0}", e); 

                ProtocolRecoveryCompleteFailureRecord.TraceAndLog(PluggableProtocol.Id(this.state.ProtocolVersion),
                                                                  PluggableProtocol.Name(this.state.ProtocolVersion),
                                                                  e); 
                throw;
            } 
            finally 
            {
                DebugTrace.TraceLeave(this, "RecoveryComplete"); 
            }
        }
    }
 
    static class TransactionManagerResponse
    { 
        // 
        // Activation
        // 

        public static void CreateTransactionResponse (Enlistment enlistment, Status status, object obj)
        {
            MsgCreateTransactionEvent e = (MsgCreateTransactionEvent) obj; 
            CompletionEnlistment completion = (CompletionEnlistment) enlistment.ProtocolProviderContext;
            completion.StateMachine.Enqueue (new TmCreateTransactionResponseEvent (completion, status, e)); 
        } 

        public static void EnlistTransactionResponse (Enlistment enlistment, Status status, object obj) 
        {
            MsgEnlistTransactionEvent e = (MsgEnlistTransactionEvent) obj;
            CoordinatorEnlistment coordinator = (CoordinatorEnlistment) enlistment.ProtocolProviderContext;
            coordinator.StateMachine.Enqueue (new TmEnlistTransactionResponseEvent (coordinator, status, e)); 
        }
 
        // 
        // Registration
        // 

        public static void RegisterResponse (Enlistment enlistment, Status status, object obj)
        {
            MsgRegisterEvent source = (MsgRegisterEvent) obj; 
            ParticipantEnlistment participant = (ParticipantEnlistment) enlistment.ProtocolProviderContext;
            participant.StateMachine.Enqueue (new TmRegisterResponseEvent(participant, status, source)); 
        } 

        public static void SubordinateRegisterResponse(Enlistment enlistment, Status status, object obj) 
        {
            InternalEnlistSubordinateTransactionEvent source = (InternalEnlistSubordinateTransactionEvent) obj;
            ParticipantEnlistment participant = (ParticipantEnlistment) enlistment.ProtocolProviderContext;
            participant.StateMachine.Enqueue(new TmSubordinateRegisterResponseEvent(participant, status, source)); 
        }
 
        // 
        // Completion
        // 

        public static void CompletionCommitResponse (Enlistment enlistment, Status status, object obj)
        {
            CompletionEnlistment completion = (CompletionEnlistment) obj; 
            completion.StateMachine.Enqueue (new TmCompletionCommitResponseEvent (completion, status));
        } 
 
        public static void CompletionRollbackResponse (Enlistment enlistment, Status status, object obj)
        { 
            CompletionEnlistment completion = (CompletionEnlistment) obj;
            completion.StateMachine.Enqueue (new TmCompletionRollbackResponseEvent (completion, status));
        }
 
        //
        // TwoPhaseCommit 
        // 

        public static void PrePrepareResponse (Enlistment enlistment, Status status, object obj) 
        {
            VolatileCoordinatorEnlistment coordinator = (VolatileCoordinatorEnlistment) obj;
            coordinator.StateMachine.Enqueue (new TmPrePrepareResponseEvent (coordinator, status));
        } 

        public static void PrepareResponse (Enlistment enlistment, Status status, object obj) 
        { 
            CoordinatorEnlistment coordinator = (CoordinatorEnlistment) obj;
            coordinator.StateMachine.Enqueue (new TmPrepareResponseEvent (coordinator, status)); 
        }

        public static void CommitResponse (Enlistment enlistment, Status status, object obj)
        { 
            CoordinatorEnlistment coordinator = (CoordinatorEnlistment) obj;
            coordinator.StateMachine.Enqueue (new TmCommitResponseEvent (coordinator, status)); 
        } 

        public static void RollbackResponse (Enlistment enlistment, Status status, object obj) 
        {
            TransactionEnlistment txEnlistment = (TransactionEnlistment) obj;
            txEnlistment.StateMachine.Enqueue (new TmRollbackResponseEvent (txEnlistment, status));
        } 
    }
} 

// 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