Il seguente codice fa parte del mio livello aziendale:
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;
}
}
}
}
A volte (una o due volte alla settimana) ottengo una TransactionInDoubtException
. stacktrace:
at System.Transactions.TransactionStateInDoubt.EndCommit(InternalTransaction tx)
at System.Transactions.CommittableTransaction.Commit()
at System.Transactions.TransactionScope.InternalDispose()
at System.Transactions.TransactionScope.Dispose()
Per quanto ne so, il livello di isolamento predefinito è serializzabile, quindi non ci dovrebbero essere problemi con questa operazione atomica. (Supponendo che non si verifichi un timeout a causa di un blocco di scrittura)
Come posso risolvere il mio problema?
Utilizzare transaction.Rollback anziché transaction.Dispose
Se una transazione in sospeso è sempre in rollback sull'eccezione.