Implementation of TransactionScope on C# Code without Database

Implementation of TransactionScope on C# Code without Database

Transaction is one of the common problems that we often use during database operation. While performing a batch data manipulation, the transaction is taken into account, such that if there is a problem in somewhere while executing a transaction, the process could be rolled back and finally when everything is complete, the Transaction gets committed or saved.

In .NET environment, there are a large number of batch operation that we perform daily and that may not really require a database in place. In .NET there is a scope of performing transactions in scope using .NET transaction objects defined inside the System.Transactions APIs such that the batches can wait for the other to perform.  The TransactionScope is the main class which can handle ambient transactions automatically. Thus using TransactionScope object lets to create a scope where batch operation can be executed.

Let us take an example.

public void StartJob()
{
    using (TransactionScope scope = new TransactionScope())
    {
        // perform some transactional work here. ... 

        if(EverythingOK)
            scope.Complete();
    }
}

As you can see we are using a Disposable block here, the Dispose would be automatically called when the scope of the Transaction ends. Now if a Complete is not called before calling Dispose, the TransactionIndoubtException will be called. The TransactionAbortedException will be called if transaction is aborted.

Related Post : Using Mutex to avoid deadlocks

TransactionScope supports Ambient Transaction which states that the transaction does not get committed unless the root transaction gets committed or aborted.

public void StartJob()
{
    using (TransactionScope scope = new TransactionScope())
    {
        // perform some transactional work here. ... 
        using (TransactionScope scope1 = new TransactionScope(TransactionScopeOption.Required))
        {
        }

        using (TransactionScope scope2 = new TransactionScope(TransactionScopeOption.RequiresNew))
        {
        }

        using (TransactionScope scope3 = new TransactionScope(TransactionScopeOption.Suppress))
        {
        }
        if (EverythingOK)
            scope.Complete();
    }

Here in the example code, nested transactions are created with the First scope being Required. The nested TransactionScope are created in simultaneously Required, as Ambient transaction is created by default, the next scope joins the parent Transaction. The Scope2 is a NewTransaction which works independent of the Ambient transaction and the scope3 also suppresses the Ambient Transaction of the global scope.

The default TransactionScope is required. Here when global scope calls Complete, the nested Ambient scope scope1 also gets committed.

You can use the TransactionScope either in Database operations using ADO.NET, or rather use them on .NET batch operations.

I hope this post would come handy.

Abhishek Sur

Abhishek Sur is a Microsoft MVP since year 2011. He is an architect in the .NET platform. He has profound theoretical insight and years of hands on experience in different .NET products and languages. He leads the Microsoft User Group in Kolkata named KolkataGeeks, and regularly organizes events and seminars in various places for spreading .NET awareness. He is associated with the Microsoft Insider list on WPF and C#, and is in constant touch with product group teams. He blogs at http://www.abhisheksur.com His Book : Visual Studio 2012 and .NET 4.5 Expert Development Cookbook. Follow Abhishek at Twitter : @abhi2434

3 Comments to “Implementation of TransactionScope on C# Code without Database”

  1. Sunny

    Sir, can you please elaborate on the concept with a real life usage? I tried the code and it’s working though but I’m getting the same output even after I’m not calling “scope.Complete();” I think I’m not clear on the concept.
    Thanks!

Comments are closed.