简体   繁体   English

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

[英]How to prevent deadlock and how to set isolation level in entity framework?

I have many deadlock in my application (asp.net mvc , entity framework code first) 我的应用程序中有很多死锁(asp.net mvc,首先是实体框架代码)

so I found some blog posts regarding deadlocks. 所以我找到了一些有关死锁的博客文章。 In one blog post here is suggested to use 在一个博客张贴在这里建议使用

 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

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

I execute this sql command on sql server and then checked the transaction isolation level which was read uncommitted. 我在sql server上执行此sql命令,然后检查未提交的事务隔离级别。

but when i run it through code using ef and linq and setting a breakpoints after the line that run "set transaction" and going back to sql to check trnasaction level it still is read committed and again i have so many deadblock. 但是,当我通过使用ef和linq的代码运行它并在运行“ set transaction”的行后设置断点并返回sql以检查trnasaction级别时,它仍然被读取为提交,并且再次出现了很多死区。

Another solution that i found is here which suggest to use scope to set isolation level 我在这里找到的另一个解决方案建议使用范围来设置隔离级别

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

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

but is it possible to use scope when using per request context? 但是在使用每个请求上下文时可以使用作用域吗?

The first question is why transaction level is still read committed after setting it to read uncommitted through dbcontext? 第一个问题是,为什么将事务级别设置为通过dbcontext读为未提交,但仍将其读为已提交?

the second question is that in this blog post it has mentioned that setting isolation level is per context does this mean that after disposing of dbcontext isolation level goes back to read committed? 第二个问题是,在此博客文章中提到了根据上下文设置隔离级别,这是否意味着在处置dbcontext隔离级别后,该级别又回到已提交状态?

and last i'm using ef code first v6 and have used unity to make dbcontext per request what other options i have so i avoid so many deadblock that are happening? 最后,我首先使用EF代码v6,并已使用unity使每个请求的dbcontext保持不变,所以我还有什么其他选择,这样可以避免发生那么多的死块?

First, check where your deadlocks are coming from. 首先,检查死锁来自何处。 That will help you find your problem areas - the areas you need to fix. 这将帮助您找到问题区域-您需要修复的区域。

Sometimes ORMs have issues with complex logic. 有时ORM会遇到逻辑复杂的问题。 One option is to provide Entity Framework with a stored procedure for reading and writing to your more data-intensive tables. 一种选择是为Entity Framework提供一个存储过程,以读取和写入更多数据密集型表。

In your controller or repository layer, you can execute a stored procedure like this: 在您的控制器或存储库层中,您可以执行如下存储过程

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

You can also use Database.ExecuteSqlCommand for procedures that do not return data. 您也可以将Database.ExecuteSqlCommand用于不返回数据的过程。

Stored procedures normally have performance gains from execution plan caching . 存储过程通常可以从执行计划缓存中获得性能提升

Using Read Uncommitted is not a magic bullet, but if you really don't care about dirty reads potentially returning bad data, then you can guarantee that your stored procedure will not take read locks by setting the serialization or using the NoLock hint. 使用“ Read Uncommitted并不是什么灵丹妙药,但是如果您真的不关心脏读可能返回错误数据,那么可以通过设置序列化或使用NoLock提示来确保存储过程不会获取读锁。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM