如何防止死锁以及如何在实体框架中设置隔离级别

本文关键字:框架 设置 隔离级 实体 何防止 死锁 | 更新日期: 2023-09-27 18:18:56

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

所以我找到了一些关于死锁的博客文章。有一篇博客文章建议使用
 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
dbcontext.database.executesqlcommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;")

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

但是当我使用ef和linq并在运行"set transaction"的行之后设置断点并返回SQL检查事务级别时,它仍然是读提交的,并且再次我有这么多死块。

我发现的另一个解决方案是在这里,建议使用作用域来设置隔离级别

using (var scope = new TransactionScope(TransactionScopeOption.Required, new 
      TransactionOptions { IsolationLevel= IsolationLevel.Snapshot }))
    {
    // do something with EF here
    scope.Complete();
    }

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

第一个问题是,为什么在通过dbcontext将事务级别设置为读取未提交后,它仍然是读取提交的?

第二个问题是,在这篇博文中提到设置隔离级别是每个上下文,这是否意味着在处理dbcontext后隔离级别回到read committed?

和最后我使用的是ef代码第一个v6,并使用统一使dbcontext每个请求我有什么其他的选择,所以我避免这么多的死块正在发生?

如何防止死锁以及如何在实体框架中设置隔离级别

首先,检查死锁是从哪里来的。这将帮助你找到你的问题所在——你需要修复的地方。

有时候orm在复杂的逻辑上有问题。一种选择是为实体框架提供一个存储过程,用于读取和写入更多数据密集型表。

在您的控制器或存储库层中,您可以执行这样的存储过程:

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

对于不返回数据的过程,也可以使用Database.ExecuteSqlCommand

存储过程通常通过执行计划缓存获得性能提升。

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