【问题标题】:How to prevent deadlock and how to set isolation level in entity framework?如何防止死锁以及如何在实体框架中设置隔离级别?
【发布时间】:2014-08-20 00:41:46
【问题描述】:

我的应用程序有很多死锁(asp.net mvc,实体框架代码优先)

所以我发现了一些关于死锁的博客文章。在一篇博文中建议使用here

 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

dbcontext.database.executesqlcommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;")

我在 sql server 上执行了这个 sql 命令,然后检查了读取未提交的事务隔离级别。

但是当我使用 ef 和 linq 通过代码运行它并在运行“设置事务”的行之后设置断点并返回到 sql 以检查 trnasaction 级别时,它仍然是读取提交的,而且我再次遇到了很多死块。

我发现的另一个解决方案是here,它建议使用范围来设置隔离级别

using (var scope = new TransactionScope(TransactionScopeOption.Required, new 
      TransactionOptions { IsolationLevel= IsolationLevel.Snapshot }))
    {

    // do something with EF here
    scope.Complete();
    }

但是在使用每个请求上下文时是否可以使用范围?

第一个问题是为什么事务级别通过dbcontext设置为read uncommitted后还是read commited?

第二个问题是,在blog post 中提到设置隔离级别是根据上下文设置的,这是否意味着在处理 dbcontext 后,隔离级别会返回到已提交的读取?

最后我首先使用 ef 代码 v6 并使用 unity 为每个请求生成 dbcontext 我还有哪些其他选项,所以我避免了这么多正在发生的死块?

【问题讨论】:

    标签: c# asp.net-mvc linq entity-framework


    【解决方案1】:

    首先,检查您的deadlocks 来自哪里。这将帮助您找到问题所在 - 您需要解决的问题。

    有时 ORM 会遇到复杂逻辑问题。一种选择是provide Entity Framework with a stored procedure 用于读取和写入数据密集型表。

    在你的控制器或存储层,你可以像这样execute a stored procedure:

    Context.Database.SqlQuery<MyEntityType>("Exec mySpName \@p0, \@p1", param1, param2);
    

    您也可以将Database.ExecuteSqlCommand 用于不返回数据的过程。

    存储过程通常有performance gains from execution plan caching。

    使用Read Uncommitted 不是灵丹妙药,但如果你真的不关心脏读可能会返回坏数据,那么你可以通过设置序列化或使用@ 来保证你的存储过程不会读锁987654329@提示。

    【讨论】:

      猜你喜欢
      • 2014-06-01
      • 1970-01-01
      • 2014-08-01
      • 2015-10-03
      • 1970-01-01
      • 2018-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多