Reputation: 19375
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 a 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 should be no problem with this atomic operation. (Assuming there is no timeout occuring because of a write lock)
How can I fix my problem?
Upvotes: 3
Views: 1869
Reputation: 391
Would it behave properly if you moved your try/catch to include the using directive for the Transaction scope? The using directive should implicitly call Dispose for you (so doing it explicitly seems redundant) and then you can throw the exception. This is what I see implement in examples from MSDN:
https://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.dispose(v=vs.110).aspx
Upvotes: -1
Reputation: 9
Add finally block to dispose the transaction. And set some status = true if you commit the transactions.
Check same in finally block and if status is true then don't rollback otherwise rollback and dispose the transaction.
Upvotes: -1
Reputation: 11
msdn says "if the transaction manager loses contact with the subordinate participant after sending the Single-Phase Commit request but before receiving an outcome notification, it has no reliable mechanism for recovering the actual outcome of the transaction. Consequently, the transaction manager sends an In Doubt outcome to any applications or voters awaiting informational outcome notification"
Please look into these links
https://msdn.microsoft.com/en-us/library/cc229955.aspx
Upvotes: 0
Reputation: 2709
Use transaction.Rollback instead of transaction.Dispose
If you have a transaction in a pending state always rollback on exception.
Upvotes: 4