我应该如何在此Entity Framework代码中处理此Optimistic Concurrency错误?

时间:2010-03-31 13:27:31

标签: .net-4.0 repository-pattern entity-framework-4 race-condition optimistic-concurrency

我在使用 EF4 存储库模式项目中有以下pseduo代码。

public void Delete(int someId)
{
   // 1. Load the entity for that Id. If there is none, then null.
   // 2. If entity != null, then DeleteObject(..);
}

非常简单,但我遇到了运行时错误: -

  

ConcurrencyException:存储,更新,   插入或删除语句受影响   意外的行数(0)。

现在,这就是发生的事情: -

  1. 两个EF4实例同时在应用程序中运行。
  2. 实例A调用delete。
  3. 实例B调用稍后删除纳秒。
  4. 实例A加载实体。
  5. 实例B也会加载实体。
  6. 实例A现在删除该实体 - 很酷的香蕉。
  7. 实例B尝试删除实体,但它已经消失了。因此,当它预期1 ..或类似的东西时,不计数或不是0。基本上,它想出了它想要删除的项目,没有删除(因为它发生在分裂前一段时间)。
  8. 我不确定这是否像种族条件或其他什么。

    无论如何,我可以在这里做任何技巧,所以第二次通话不会崩溃吗?我可以将其变成存储过程..但我希望现在能避免这样做。

    有什么想法吗?我想知道如果在调用select时可以锁定该行(并且仅限该行)...强制实例B等待直到行锁被重新启动。到那时,该行被删除,所以当实例B选择时,数据不存在......所以它永远不会被删除。

1 个答案:

答案 0 :(得分:0)

通常,您会捕获OptimisticConcurrencyException,然后以对您的业务模型有意义的方式处理问题 - 然后再次调用SaveChanges。

try
{
    myContext.SaveChanges();
}
catch (OptimisticConcurrencyException e)
{
    if (e.StateEntries.FirstOrDefault() is DeletingObject)
        myContext.Detach(e.StateEntries.First();
    myContext.SaveChanges();
}

给它一个旋转,看看你是如何进行的 - 没有测试/编译或任何东西 - 我已经使用DeletingObject作为你想要删除的实体的类型。替换您的实体类型。