Transaction Timeout in System.Transactions

Posted: February 1, 2009 in .NET, Transactions
Tags: ,

Recently I was working on a strange problem faced by a development team.They had used .NET 2.0 Lightweight Transaction Manager provided by the classes under System.Transaction namespace.Within the TransactionScope a long running database job was executing.They faced an intermittent TransactionAbortedException saying “Transaction has been aborted”.

After taking a look into the code it was found that they are using a ADO.NET Command Timeout of about 900s.But there is no command timeout set for the Transaction.The default timeout period of Transaction is 60s.So there can be a situation where the database job is taking more than a minute to complete and Transaction Manager is aborting the transaction as transaction timeout has expired even though database process has not timed out.

We can set the Transaction timeout in two ways using the constructor of the TransactionScope class or config.

  • The following two constructors of TransactionScope class accepts a TimeSpan parameter which defines the timeout period for the code executing within the context of that TransactionScope.
    • public TransactionScope(Transaction transactionToUse,TimeSpan scopeTimeout)
    • public TransactionScope(TransactionScopeOption scopeOption,TimeSpan scopeTimeout)
  • We can also define the timeout in the application configuration (web.config or app.config) as shown

                 <system.transactions>

                       <defaultSettings timeout=”02:00:00″/>

                </system.transactions>

            We need to define the max timeout setting at machine level in machine.config

            <system.transactions>
                    <machineSettings maxTimeout=”02:00:00″/>
            </system.transactions>

But it was very surprising that there was no timeout exception instead a transaction aborted message which was very confusing.Then I came to know from the following MSDN Forum post that timeout is actually wrapped as an inner exception:

http://social.msdn.microsoft.com/forums/en-US/adodotnetdataproviders/thread/9f9c1d11-6c0d-423e-bffc-4d1957e9bdd7

Then I wrote the following snippet to simulate the situation:

using(TransactionScope scope = new TransactionScope(
                                TransactionScopeOption.RequiresNew,
                                new TimeSpan(0,0,30)))
{
     Console.WriteLine(“Entered Transaction Scope”);
     System.Threading.Thread.Sleep(60000);
     Console.WriteLine(“Start Commit”);
     scope.Complete();
     Console.WriteLine(“Transaction Complete.”);
}

Here I have set transaction timeout 30 s and the code block will take 60 s to execute.

The program threw an exception as shown below:

timeout

But surprisingly the exception was not thrown just after 30 s elapsed.The exception was thrown after the entire code block completed it’s execution.The exception was thrown while exiting from the using {} block.So I changed the code as follows:

try
          {
              Console.WriteLine(“Entered Transaction Scope”);
              System.Threading.Thread.Sleep(60000);
              Console.WriteLine(“Start Commit”);
              scope.Complete();
              Console.WriteLine(“Transaction Complete.”);
          }
          catch
          {
              throw;
          }
          finally
          {
              scope.Dispose();
          }

Then I found out that this exception is thrown from scope.Dispose();

Comments
  1. niko says:

    There is a maxtimeout (10mns) set by default at the machine level (see machine.config)

  2. sankarsan says:

    Did not quite get your point.I thought I had mentioned that:-)

  3. Mike says:

    Just passing by.Btw, your website have great content!

    _________________________________
    Making Money $150 An Hour

  4. Cosmin says:

    The exception is thrown at scope.Dispose() operation because:

    “…you should also note that calling this method (TransactionScope.Complete()) does not guarantee a commit of the transaction. It is merely a way of informing the transaction manager of your status”

    “The actual work of commit between the resources manager happens at the End Using statement if the TransactionScope object created the transaction”

  5. Sam says:

    Nice explaination!!! Thanks.

    Pls share ur threads with me.

    Thanks,
    SAM.

  6. Venkat says:

    What is the solution to fix this issue. I am also running to similar kind of issue.

  7. Hanumanth says:

    I am also facing same issue. What is the fix for above Transactionabortexception. Please explain me.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.