transactioncontext.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / System.ServiceModel.Activities / System / ServiceModel / Activities / Dispatcher / transactioncontext.cs / 1305376 / transactioncontext.cs

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

namespace System.ServiceModel.Activities.Dispatcher 
{
    using System.Runtime; 
    using System.Transactions; 

    //1) On Tx.Prepare 
    //    Persist the instance.
    //          When Persist completes Tx.Prepared called.
    //          When Persist fails Tx.ForceRollback called.
    //2) On Tx.Commit 
    //     DurableInstance.OnTransactionCompleted().
    //3) On Tx.Abort 
    //     DurableInstance.OnTransactionAborted() 
    class TransactionContext : IEnlistmentNotification
    { 
        static AsyncCallback handleEndPrepare = Fx.ThunkCallback(new AsyncCallback(HandleEndPrepare));
        Transaction currentTransaction;
        WorkflowServiceInstance durableInstance;
 
        public TransactionContext(WorkflowServiceInstance durableInstance, Transaction currentTransaction)
        { 
            Fx.Assert(durableInstance != null, "Null DurableInstance passed to TransactionContext."); 
            Fx.Assert(currentTransaction != null, "Null Transaction passed to TransactionContext.");
 
            this.currentTransaction = currentTransaction.Clone();
            this.durableInstance = durableInstance;
            this.currentTransaction.EnlistVolatile(this, EnlistmentOptions.EnlistDuringPrepareRequired);
        } 

        public Transaction CurrentTransaction 
        { 
            get
            { 
                return this.currentTransaction;
            }
        }
 
        void IEnlistmentNotification.Commit(Enlistment enlistment)
        { 
            enlistment.Done(); 
            this.durableInstance.TransactionCommitted();
        } 

        void IEnlistmentNotification.InDoubt(Enlistment enlistment)
        {
            enlistment.Done(); 
            Fx.Assert(this.currentTransaction.TransactionInformation.Status == TransactionStatus.InDoubt, "Transaction state should be InDoubt at this point");
            TransactionException exception = this.GetAbortedOrInDoubtTransactionException(); 
 
            Fx.Assert(exception != null, "Need a valid TransactionException at this point");
            this.durableInstance.OnTransactionAbortOrInDoubt(exception); 
        }

        void IEnlistmentNotification.Prepare(PreparingEnlistment preparingEnlistment)
        { 
            bool success = false;
            try 
            { 
                IAsyncResult result = new PrepareAsyncResult(this, TransactionContext.handleEndPrepare, preparingEnlistment);
                if (result.CompletedSynchronously) 
                {
                    PrepareAsyncResult.End(result);
                    preparingEnlistment.Prepared();
                } 
                success = true;
            } 
            //we need to swollow the TransactionException as it could because another party aborting it	 
            catch (TransactionException) {}
            finally 
            {
                if (!success)
                {
                    preparingEnlistment.ForceRollback(); 
                }
            } 
        } 

        void IEnlistmentNotification.Rollback(Enlistment enlistment) 
        {
            enlistment.Done();
            Fx.Assert(this.currentTransaction.TransactionInformation.Status == TransactionStatus.Aborted,"Transaction state should be Aborted at this point");
            TransactionException exception = this.GetAbortedOrInDoubtTransactionException(); 

            Fx.Assert(exception != null, "Need a valid TransactionException at this point"); 
            this.durableInstance.OnTransactionAbortOrInDoubt(exception); 
        }
 
        TransactionException GetAbortedOrInDoubtTransactionException()
        {
            try
            { 
                Fx.ThrowIfTransactionAbortedOrInDoubt(this.currentTransaction);
            } 
            catch (TransactionException exception) 
            {
                return exception; 
            }
            return null;
        }
 
        static void HandleEndPrepare(IAsyncResult result)
        { 
            PreparingEnlistment preparingEnlistment = (PreparingEnlistment)result.AsyncState; 
            bool success = false;
            try 
            {
                if (!result.CompletedSynchronously)
                {
                    PrepareAsyncResult.End(result); 
                    preparingEnlistment.Prepared();
                } 
                success = true; 
            }
            //we need to swollow the TransactionException as it could because another party aborting it 
            catch (TransactionException) {}
            finally
            {
                if (!success) 
                {
                    preparingEnlistment.ForceRollback(); 
                } 
            }
        } 

        class PrepareAsyncResult : AsyncResult
        {
            static readonly AsyncCompletion onEndPersist = new AsyncCompletion(OnEndPersist); 

            readonly TransactionContext context; 
 
            public PrepareAsyncResult(TransactionContext context, AsyncCallback callback, object state)
                : base(callback, state) 
            {
                this.context = context;

                IAsyncResult result = null; 
                using (PrepareTransactionalCall(this.context.currentTransaction))
                { 
                    result = this.context.durableInstance.BeginPersist(TimeSpan.MaxValue, PrepareAsyncCompletion(PrepareAsyncResult.onEndPersist), this); 
                }
                if (SyncContinue(result)) 
                {
                    Complete(true);
                }
            } 

            public static void End(IAsyncResult result) 
            { 
                AsyncResult.End(result);
            } 

            static bool OnEndPersist(IAsyncResult result)
            {
                PrepareAsyncResult thisPtr = (PrepareAsyncResult)result.AsyncState; 
                thisPtr.context.durableInstance.EndPersist(result);
                thisPtr.context.durableInstance.OnTransactionPrepared(); 
                return true; 
            }
        } 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

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