c# - 同时运行这两个语句时如何防止 EntityFramework 死锁

标签 c# entity-framework deadlock

调用我的网络服务使用以下代码来确保调用者具有有效 session 。如果找到有效 session ,则它会更新 session 详细信息并保存更改。一切都很简单并且工作正常。

// Create the Entity Framework context
using(MyContext ctx = CreateMyContext())
{
     // Get the user session for the client session         
     UserSession session = (from us in context.UserSessions.Include("UserEntity")
                            where us.SessionId = callerSessionId
                            select us).FirstOrDefault<UserSession>();

     if (session == null)
         return false;
     else
     {
         // Update session details
         session.Calls++;
         session.LastAccessed = DateTime.Now.Ticks;
         Console.WriteLine("Call by User:{0}", session.UserEntity.Name);

         // Save session changes back to the server
         ctx.SaveChanges();
         return true;
     }    
}

所有工作正常,直到同一个调用者,因此同一个 session ,进行多个并发调用(这是完全有效的发生)。在这种情况下,我有时会陷入僵局。使用 SQL Server Profiler 我可以看到发生了以下情况。

调用方 A 执行选择并获取用户 session 的共享锁。调用方 B 执行选择并在同一用户 session 上获取共享锁。由于调用者 B 的共享锁,调用者 A 无法执行其更新。由于调用者 A 的共享锁,调用者 B 无法执行其更新。死锁。

这似乎是一个简单而经典的死锁场景,必须有一个简单的方法来解决它。几乎所有现实世界的应用程序肯定都存在同样的问题。但是我没有提到任何关于死锁的 Entity Framework 书籍。

最佳答案

我找到了一篇讨论这个的文章 HERE .基本上听起来您可以启动和停止围绕您的 EF 调用的事务...该 block 提供了以下代码示例,因此归功于 Diego B Vega...该博客文章还链接到另一个包含其他信息的博客。

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

关于c# - 同时运行这两个语句时如何防止 EntityFramework 死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13097179/

相关文章:

c# - 在 javascript 中查找控件

c# - 复杂对象不能被同一个实体多次引用

c# - 已经有一个打开的 DataReader ...即使它不是

C# 新字段和 foreach

c# - 复杂类型字段

c# - .NET核心6 : Use my DbContext in Authorization Handler

c# - 锁定一个简单的属性 - 它会死锁吗?

java - 调试 Hibernate/Ehcache 死锁

java - Java 中的多线程死锁

c# - 如何使用 ASP.NET 和 jQuery 返回 JSON