none
TransactionScope - random timeout in multi-threaded environment RRS feed

  • Question

  •  

    I have a large collection (can be in excess of 100,000 objects) of custom object that require updating to a database. I process these in a multi-threaded environment using a queue processor that looks similar to a producer-consumer model.

     

    When the worker threads execute they remove an object from the queue and pass it to a process method. Within this method i create a TransactionScope object and persist the object. This all works fine and i get a massive increase in performance BUT occassionally i get a timeout when the TransactionScope executes it's Dispose() method (basically at the end of the using block). A TransactionAbortedException is thrown with a TimeoutException as an inner exception.

     

    I have no idea why it's timing out. There is no blocking in the database that might cause it. It's not a dead lock as everything is processed in the same way (and as it's processing > 400 transactions per second/1200 stored procedures per second).

     

    This seems to be related to the multiple threads and when it does happen it only happens on a thread once and generally at the end of the cycle. Also, this doesn't happen on my PC that only has 1 CPU, it only occurs on my server that has 2 CPUs.

     

    I understand that when TransactionScope.Dispose() method gets called it commits the underlying transaction. I presume it's at this point that something is hanging. Increasing the timeout doesn't work. I have increased it to 1 hour and it will hang for 1 hour. This appears to be a bug somewhere within the Dispose method.

     

    Stack Trace of TransactionAbortedException:

     

       at System.Transactions.TransactionStatePromotedAborted.PromotedTransactionOutcome(InternalTransaction tx)
       at System.Transactions.TransactionStatePromotedEnded.EndCommit(InternalTransaction tx)
       at System.Transactions.CommittableTransaction.Commit()
       at System.Transactions.TransactionScope.InternalDispose()
       at System.Transactions.TransactionScope.Dispose()
       at BusinessObjectLayerBase.BusinessObjectBase.PersistCollectionTasks`1.Process(T item, Object state) in F:\Source Code\Enterprise\ExpoBillingServer\BoTest\BusinessObjectBase.cs:line 744

     

    IDEAS ANYONE?

    Tuesday, July 24, 2007 3:42 PM