如何在实体框架中使用TransactionScope

本文关键字:TransactionScope 框架 实体 | 更新日期: 2023-09-27 18:22:31

我正在使用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中运行。我想知道我的代码是否有任何问题?如果是,我该怎么做才能避免出现死锁情况?

如何在实体框架中使用TransactionScope

如果您只使用一个上下文来保存数据。您不需要使用TransactionScope。当您调用SaveChanges时,Ef会自动登记所有更改并将它们应用于单个事务。对于分布式事务,必须使用TransactionScope。

[link]使用Transactions还是SaveChanges(false)和AcceptAllChanges()?

https://coderwall.com/p/jnniww/why-you-shouldn-t-use-entity-framework-with-transactions

考虑使用异步方法来进行繁重的计算。

using (var transaction = Database.BeginTransaction())
{
    try
    {
        var heavyCalulation = await heavyCalulationMethodAsync();
        await context.SaveChangesAsync();
    }
    catch
    {
        transaction.Rollback();
    }
}

避免死锁的唯一方法是每次执行更新的操作都以相同的表顺序访问和更新记录。

在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

相关文章:
  • 没有找到相关文章