DCSIMG
WCF Transactions – Barebones Demo - Part 1 - David Sackstein's Blog

WCF Transactions – Barebones Demo - Part 1

In this post we will prepare two tools that will help us trace WCF’s transaction support in our demo. Both tools can be found in the Common class library in the source code.

The other posts in this series are:

WCF Transactions – Barebones Demo – Overview (Tools)

WCF Transactions – Barebones Demo – Part 2 (Service Code)

WCF Transactions – Barebones Demo – Part 3 (Client Code)

WCF Transactions – Barebones Demo – Part 4 (Analysis)

You can download the source code for the series from here.

The first tool is an implementation IEnlistmentNotification - our own Resource Manager. As mentioned in the overview this class is far from complete. For a start, it doesnt support isolation between transactions. But in this demo we will assume that there is at most only one transaction trying to access the resource.

    public class VolatileResourceManager<T> : IEnlistmentNotification

    {

        #region Private

 

        private T oldValue = default(T);

        private T newValue = default(T);

        private T currValue = default(T);

 

        #endregion

 

        #region Singleton

 

        private static VolatileResourceManager<T> instance =

            new VolatileResourceManager<T>();

 

        private VolatileResourceManager() {}

 

        public static VolatileResourceManager<T> Instance

        {

            get { return instance; }

        }

 

        #endregion

 

        #region Public

 

        public T Get()

        {

            return this.currValue;

        }

 

        public void Set(T value)

        {

            Transaction transaction = Transaction.Current;

            if (transaction == null)

            {

                Console.Write("Set without transaction");

                this.currValue = value;

            }

            else

            {

                transaction.Log();

 

                Console.Write("Set with Transaction with EnlistVolatile");

 

                transaction.EnlistVolatile(this, EnlistmentOptions.None);

               

                oldValue = this.currValue;

                newValue = value;

            }

        }

 

        #endregion

 

        #region IEnlistmentNotification Members

 

        public void Commit(Enlistment enlistment)

        {

            Console.Write("Commit");

            oldValue = default(T);

        }

 

        public void InDoubt(Enlistment enlistment)

        {

            Console.Write("InDoubt");

        }

 

        public void Prepare(PreparingEnlistment preparingEnlistment)

        {

            Console.Write("Prepare");

            this.currValue = newValue;

            preparingEnlistment.Prepared();

            // or

            //preparingEnlistment.ForceRollback();

        }

 

        public void Rollback(Enlistment enlistment)

        {

            Console.Write("Rollback");

 

            this.currValue = oldValue;

            oldValue = default (T);

        }

 

        #endregion

    }

The implementation of IEnlistmentNotification is fairly simple, using the two private variables oldValue and newValue to manage state until either Rollback or Commit determine the final value for the transaction.

The Set method is the interesting one.

Here, we check whether there is an ambient transaction in progress. If not, we just set the currValue and return. If there is, we update newValue and remember oldValue in preparation for the two phase commit protocol.

The call to transaction.Log() will print on the console whether the transaction is a local or distributed transaction and also print its identifier. This will be useful when we want to verify that a transaction initiated by a client has been propagated over a service boundary.

The Log() method is the second tool in the Common class library. It is an extension method for the Transaction class defined as follows:

    public static class TransactionExtensions

    {

        public static void Log(this Transaction transaction)

        {

            TransactionInformation info = transaction.TransactionInformation;

 

            if (info.DistributedIdentifier == Guid.Empty)

            {

                Console.WriteLine ("{0} :", Process.GetCurrentProcess().ProcessName);

                Console.WriteLine("   Local Transaction " + info.LocalIdentifier);

            }

            else

            {

                Console.WriteLine("Distributed Transaction " + info.DistributedIdentifier);

            }

        }

    }

You may have noticed that I defined the VolatileResourceManager as a singleton. The reason for that is related to the way WCF handles service instances that take part in transactions.

More on that in Part 2.

Published Sunday, June 14, 2009 11:15 PM by David Sackstein

Comments

# WCF Transactions – Barebones Demo – Part 2

Monday, June 15, 2009 1:47 AM by David Sackstein's Blog

In this post we will develop a WCF service that is capable of participating in a client transaction.

# WCF Transactions ??? Barebones Demo ??? Overview - David Sackstein&#39;s Blog

Pingback from  WCF Transactions ??? Barebones Demo ??? Overview - David Sackstein&#39;s Blog

# WCF Transactions ??? Barebones Demo ??? Part 3 - David Sackstein&#39;s Blog

Pingback from  WCF Transactions ??? Barebones Demo ??? Part 3 - David Sackstein&#39;s Blog

# WCF Transactions ??? Barebones Demo ??? Part 4 - David Sackstein&#39;s Blog

Pingback from  WCF Transactions ??? Barebones Demo ??? Part 4 - David Sackstein&#39;s Blog

Leave a Comment

(required) 
(required) 
(optional)
(required) 

Enter the numbers above:
Powered by Community Server (Commercial Edition), by Telligent Systems