TransactionScope TransactionInDoubtException in EntityFramework

The following code is part of my business layer:

   public void IncrementHits(int ID)
    {
        using (var context = new MyEntities())
        {
            using (TransactionScope transaction = new TransactionScope())
            {
                Models.User userItem = context.User.First(x => x.IDUser == ID);
                userItem.Hits++;
                try
                {
                    context.SaveChanges();
                    transaction.Complete();
                }
                catch (Exception ex)
                {
                    transaction.Dispose();
                    throw;
                }

            }
        }
    }

      

Sometimes (once or twice a week) I get TransactionInDoubtException

. Stacktrace:

at System.Transactions.TransactionStateInDoubt.EndCommit(InternalTransaction tx) 
at System.Transactions.CommittableTransaction.Commit() 
at System.Transactions.TransactionScope.InternalDispose() 
at System.Transactions.TransactionScope.Dispose() 

      

As far as I know, the default isolation level is serializable, so there shouldn't be any problem with this atomic operation. (Assuming no timeout due to write lock)

How can I fix my problem?

+3


source to share


4 answers


Use transaction .Rollback instead of transaction.



If you have a pending transaction, it always rolls back on exception.

+4


source


msdn says, "If a transaction manager loses contact with a subordinate after sending a one-phase commit request, but before receiving notification of the results, it has no reliable mechanism to recover the actual result of the transaction. Therefore, the transaction manager sends the result" Doubt "to any claims or voters pending notification of information outcome "

Please check out these links



https://msdn.microsoft.com/en-us/library/cc229955.aspx

https://msdn.microsoft.com/en-us/library/system.transactions.ienlistmentnotification.indoubt(v=vs.85).aspx

0


source


Add the final block to delete the transaction. And set some status = true if you are making transactions.

Check the same in the finally block and if status is true then do not rollback otherwise rollback and delete the transaction.

0


source


Will it behave correctly if you moved the try / catch to include a use directive for the transaction scope? The using directive should implicitly call Dispose for you (so this is clearly overkill) and then you can throw an exception. This is what I see in examples from MSDN:

https://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.dispose(v=vs.110).aspx

0


source







All Articles