SVI
SVI

Reputation: 951

Unit Of Work inside Transaction scope and Entity Framework

I get an exception when I try to save an entity inside a TransactionScope, the exception I get is:

The operation is not valid for the state of the transaction

However on another machine I get a different exception on the same code block:

The transaction operation cannot be performed because there are pending requests working on this transaction

The transaction implementation in my method is:

    TransactionHelper.Transaction(() =>
    {
        if (sys.WfId.HasValue)
        {
            var sysData = GeneralMapping.GetSysData(model, ThisUser);
            DoAction(sys, model, sysData);

            if (!_sysClosed)
            {
                _Repository.InsertOrUpdate(sys);
                _Uow.Save();
            }
        }

    });

TransactionHelper:

public static class TransactionHelper
{
    public static void HandleTransaction(Action action)
    {
        using (var tx = CreateScope())
        {
            action();
            tx.Complete();
        }
    }

    private static TransactionScope CreateScope(IsolationLevel isolationLevel = IsolationLevel.ReadCommitted)
    {
         var tOptions = new TransactionOptions
                                 {
                                     IsolationLevel = isolationLevel,
                                     Timeout = TransactionManager.MaximumTimeout
                                 };
         return new TransactionScope(TransactionScopeOption.Required, tOptions);
    }

}

This was working perfectly well without any problem, however recently after I started to see these exceptions, I have been told that this implementation might lead into a deadlocks, as the unit of work is a transaction (Business Transaction - Martin Fowler) inside a transaction scope, is that possible to be the reason? and if so, what can be the alternative implementation if needed?

Upvotes: 3

Views: 2664

Answers (1)

Mohsen Esmailpour
Mohsen Esmailpour

Reputation: 11554

This exception occurred by several reasons like transaction timeout, nesting two transactions inside each other, two open connection inside of transaction scope, using single DbContext instance for entire web application and hence DbContext has it's own UOF, it may some conflict occurs between theme for some reason. You can use System.Transactions.Transaction.Current.TransactionInformation.Status for identifying status of transaction and it my aborted before exception thrown.

Change return new TransactionScope(TransactionScopeOption.Required, tOptions); to return new TransactionScope(TransactionScopeOption.RequiresNew, tOptions); and test it again and see what happen.

Upvotes: 1

Related Questions