Click here to Skip to main content
15,896,118 members
Articles / Web Development / IIS

Transactional Web Services with WS-AtomicTransaction

Rate me:
Please Sign up or sign in to vote.
3.91/5 (12 votes)
12 Jun 2008CPOL6 min read 137.4K   491   48  
Explains a simple way of using WS-AtomicTransaction to create distributed transactions across Web services
using System;
using System.Collections;
using System.Transactions;
using ClientSide;
using Common;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Test01_SaveDelete();
            Console.WriteLine("\n\n");
            Test02_Transaction();
        }

        public static void Test01_SaveDelete()
        {
            Console.WriteLine("This test will create two different objects and save them to the");
            Console.WriteLine("database.  Then it will delete them.  The purpose of this test is");
            Console.WriteLine("to make sure that the whole program is working from client to");
            Console.WriteLine("server and back.");
            Console.WriteLine("\n\nCreate our transaction controller.");
            using (TransactionalWebServiceProxy proxy = new TransactionalWebServiceProxy())
            {
                Console.WriteLine("First check the number of rows in the table.");
                int origNumRows = proxy.GetAllCategories().Count;

                using (TransactionScope scope = new TransactionScope())
                {
                    Console.WriteLine("Save first object.");
                    Category category1 = new Category();
                    category1.Name = "My New Category";
                    category1.Description = "Delete Me";
                    category1.CategoryId = proxy.CreateCategory(category1);

                    Console.WriteLine("Save second object.");
                    Category category2 = new Category();
                    category2.Name = "Second Category";
                    category2.Description = "I am test data";
                    category2.CategoryId = proxy.CreateCategory(category2);

                    Console.WriteLine("Delete first object.");
                    proxy.DeleteCategory(category1.CategoryId);
                    Console.WriteLine("Delete second object.");
                    proxy.DeleteCategory(category2.CategoryId);

                    scope.Complete();
                }

                Console.WriteLine("With the transaction finished, let's check if the number of rows");
                Console.WriteLine("matches the original number.");
                int newNumRows = proxy.GetAllCategories().Count;
                if (newNumRows != origNumRows)
                    Console.WriteLine("The numbers do not match, something failed.");
                else
                    Console.WriteLine("The numbers match, this was a success.");
            }
        }

        public static void Test02_Transaction()
        {
            Console.WriteLine("This test is intended to actually check if the transaction works");
            Console.WriteLine("like it's supposed to.  It will save one object to the database");
            Console.WriteLine("and then attempt to delete one that is not in the database.  If");
            Console.WriteLine("the transaction works, the saved object should not be in the");
            Console.WriteLine("database.");

            int origNumRows = -1;
            try
            {
                using (TransactionalWebServiceProxy proxy = new TransactionalWebServiceProxy())
                {
                    Console.WriteLine("First check the number of rows in the table.");
                    origNumRows = proxy.GetAllCategories().Count;

                    using (TransactionScope scope = new TransactionScope())
                    {
                        Console.WriteLine("Save an object.");
                        Category category = new Category();
                        category.Name = "I don't belong";
                        category.Description = "Delete Me";
                        category.CategoryId = proxy.CreateCategory(category);

                        Console.WriteLine("Delete an object that doesn't exist.");
                        proxy.DeleteCategory(666);

                        Console.WriteLine("We should not get here.");
                        scope.Complete();
                    }
                }
            }
            catch
            {
                Console.WriteLine("We were expecting to get an exception here.");
            }

            using (TransactionalWebServiceProxy proxy = new TransactionalWebServiceProxy()) 
            {
                Console.WriteLine("With the transaction finished, let's check if the number of rows");
                Console.WriteLine("matches the original number.  Also notice that the old channel");
                Console.WriteLine("is in the faulted state and cannot be used again.");
                int newNumRows = proxy.GetAllCategories().Count;
                if (newNumRows != origNumRows)
                    Console.WriteLine("The numbers do not match, something failed.");
                else
                    Console.WriteLine("The numbers match, this was a success.");
            }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Microsoft
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions