以下代码是我的业务层的一部分:
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;
}
}
}
}
有时候(每周一次或两次)我得到TransactionInDoubtException
。 Stacktrace:
at System.Transactions.TransactionStateInDoubt.EndCommit(InternalTransaction tx)
at System.Transactions.CommittableTransaction.Commit()
at System.Transactions.TransactionScope.InternalDispose()
at System.Transactions.TransactionScope.Dispose()
据我所知,默认的隔离级别是可序列化的,因此这个原子操作应该没有问题。 (假设由于写锁定而没有超时)
如何解决问题?
答案 0 :(得分:4)
使用transaction.Rollback而不是transaction.Dispose
如果事务处于挂起状态,则始终在异常时回滚。
答案 1 :(得分:0)
请查看这些链接
答案 2 :(得分:0)
添加finally块以处理事务。如果提交事务,请设置一些status = true。
在finally块中检查相同,如果status为true,则不要回滚,否则回滚并处理该事务。
答案 3 :(得分:0)
如果您将try / catch移动到包含Transaction范围的using指令,它会表现得正常吗? using指令应该隐式为你调用Dispose(这样做显然看起来多余)然后你可以抛出异常。这就是我在MSDN的示例中看到的实现:
https://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.dispose(v=vs.110).aspx