我正在使用ASP.NET MVC和实体框架开发学生阅卷系统。我使用了一个很重的方法来计算标记。在给定时间,大约有50个用户向系统输入标记,所有用户都调用繁重的方法。它会让我大部分时间陷入僵局。我正在使用TransactionScope
。
这是我的代码:
try
{
using (context = new SIMSDBAPPEntities())
{
using (TransactionScope scope = new TransactionScope())
{
// My heavy calculation
}
scope.Complete();
context.SaveChanges();
}
catch (Exception ex)
{
throw ex;
}
}
我的重方法是在TransactionScope
中运行。我想知道我的代码有没有问题?如果是,我可以做些什么来避免死锁情况?
发布于 2015-11-19 02:46:05
如果您只使用一个上下文来保存数据。你不需要使用TransactionScope。当您调用SaveChanges Ef时,自动登记所有更改并将其应用于单个事务。对于分布式事务,必须使用TransactionScope。
https://coderwall.com/p/jnniww/why-you-shouldn-t-use-entity-framework-with-transactions
发布于 2015-11-19 02:17:13
考虑使用异步方法进行繁重的计算。
using (var transaction = Database.BeginTransaction())
{
try
{
var heavyCalulation = await heavyCalulationMethodAsync();
await context.SaveChangesAsync();
}
catch
{
transaction.Rollback();
}
}
发布于 2015-11-19 02:35:35
避免死锁的唯一方法是,每次执行更新操作时,都以相同的表顺序访问和更新记录。
这在像EF和nHibernate这样的ORM中很难实现,因为表操作的概念隐藏在实现的背后。无论框架决定什么策略,你都要听天由命。要解决这个问题,您必须小心地逐个更新对象并逐个对象地保存您的更改。对于执行更新的每个操作,您还必须确保始终以相同的顺序保存这些对象。
我在过去为最小化这个问题所做的是为隔离快照启用数据库,并将该方法用于您的事务作用域。
https://msdn.microsoft.com/en-us/library/tcbchxcb(v=vs.110).aspx
这里也有可能出错的一些事情(比如写回一个过时的记录)。但我发现它发生的频率比死锁要少。
我发现这篇文章也很有帮助(并给出了快照隔离的例子)。http://blogs.msdn.com/b/diego/archive/2012/04/01/tips-to-avoid-deadlocks-in-entity-framework-applications.aspx
https://stackoverflow.com/questions/33787175
复制相似问题