Manage your transaction chaos with Spring Framework

April 30th, 2008 by Sameer | Filed under .NET articles.

Spring is a popular framework available in Java.  It has also been published in .NET and is called Spring.NET

This framework is huge, but what I wanted to focus on is the section that deals with transaction management.

If you have ever worked with Transactions, (say SQLTransactions), you would realize how messy it can be when you have to keep your connection open and pass around a transaction to many different functions that are making updates or queries, and then you might make a small little change and find out you forgot to use the transaction object and you caused a deadlock!

How can you fix this?  By having a generic transaction/connection object?  Well, that’s one way.. but how about using the Spring.NET framework to deal with the transactions?

Spring.NET allows you to specify when you need a transaction, and you would begin and end the transaction.  However, when you do the actual database calls, you would not pass any connection string, it would automatically use the transaction in process if there is one, or if not needed then it would use a regular connection and disconnect after the query is complete.

Here is a code snippet to demonstrate programmative transaction management, taken from the Spring.NET source code (yeah its open source!)

 

[Test]
        public void ExecuteTransactionManager()
        {
            DefaultTransactionDefinition def = new DefaultTransactionDefinition();
            def.PropagationBehavior = TransactionPropagation.Required;

            //TODO change to property of name TransactionStatus...
            ITransactionStatus status = transactionManager.GetTransaction(def);

            int iCount = 0;
            try
            {
                iCount = (int)adoOperations.ExecuteScalar(CommandType.Text, "SELECT COUNT(*) FROM TestObjects");
                /*
                IAdoCommand cmd = new AdoCommand(dbProvider, CommandType.Text);
                cmd.CommandText = "SELECT COUNT(*) FROM TestObjects";
                iCount = (int)cmd.ExecuteScalar();
                */

                //other AdoCommands can be executed within same tx.
            } catch (Exception e)
            {
                transactionManager.Rollback(status);
                throw e;
            }
            transactionManager.Commit(status);
            Assert.AreEqual(2, iCount);

        }

As you can see from this code, the adoOperations.ExecuteScalar does not have any connection string passed to it.  Same thing with ExecuteDataSet, and so on. 

This actually saves you a lot of headache, as you just have to make sure you use the spring DataOperations object.  The easiest way to implement this on a ASP.NET site is to put these objects as a static variable and initialize them on Application_Load.  Just an idea but it should work. 

 If you want to do more digging, Spring.NET has tons of stuff, it seems to mostly focus on Dependency Injection and loose coupling of code from objects from the data layer.  I really like it and I recommend you give it a shot.

It’s proven itself in Java and I think this framework is going to prove itself in .NET as well.  At the very least the source code is a prime example of a clean object oriented well designed application with full unit tests and sample code, XML documentation, thorough use of interfaces and inheritance, and even ORM (object relational mapping) using NHibernate (again a popular Java framework which has come into .NET)

 Update: I called this "declarative transaction management", actually its "programmative transaction management". – FIXED

Other Interesting Posts

Leave a Reply