2

我在某些存储库模式中有以下pseduo代码项目使用EF4我该如何处理这个实体框架代码中的这个乐观并发错误?

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: Store, Update, Insert or Delete statement affected an unexpected number of rows (0).

现在,这是发生了什么: - EF4的

  1. 两个实例在矿井运行应用程序在同一时间。
  2. 实例A调用delete。
  3. 实例B调用稍后删除纳秒。
  4. 实例A加载实体。
  5. 实例B还加载实体。
  6. 实例A现在删除该实体 - 酷香蕉。
  7. 实例B尝试删除该实体,但它已经消失。因此,无计数或什么不是0,当它预期1 ..或类似的东西。基本上,它发现它想要删除的项目没有删除(因为它发生在一秒钟之前)。

我不确定这是否像竞争条件什么的。

反正,有没有什么技巧我可以在这里做,所以第二个电话不会崩溃?我可能使它成为一个存储过程..但我希望能够避免现在。

任何想法?我想知道是否有可能在选择被调用时锁定该行(以及仅该行)...迫使实例B等待行锁定已被关闭。到那个时候,该行被删除,所以当实例B选择时,数据不在那里..所以它永远不会删除。

+0

你为什么不处理并发异常?如果该对象已从另一个线程(又名EF实例)中删除,则该线程没有工作,因为该记录已被删除。 – 2010-03-31 14:01:35

+0

这就是问题 - >两个实例都认为它们有一个要删除的对象,因为它们都从数据库中同时读取。只是实例A实际上在第二次调用之前的纳秒内完成DeleteObject(..)方法..对于同一个对象。现在,我的处理异常..但我觉得这是避免真正的问题..我想知道是否可以做一些锁定或什么处理? – 2010-03-31 20:31:29

回答

0

通常你会赶上OptimisticConcurrencyException再处理的方式,是有道理的,你的商业模式问题 - 然后再调用的SaveChanges。

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

给一个旋转,看看你上车 - 没有测试/编译或任何东西 - 我用DeletingObject如你想删除的实体的类型。替代您的实体类型。

+0

嗯 - 有趣。你能否真正解释你在捕捉时想做什么?因此,与我最初的例子,如果Instance_B请问删除..它抛出异常..然后你想看看分离..已删除对象(因为它不应该存在?) – 2010-05-14 13:57:42

+0

通过分离已被删除的对象,我试图阻止状态管理器将该删除操作推送到数据库。应该删除的对象仍然附加,它具有删除的实体状态。我刚刚运行了一个快速测试并调用.DeleteObject(myObject)后跟.Detach(myObject)后跟.SaveChanges()不推送删除。给它一个去看看,看看它是否有帮助。 – 2010-05-17 08:45:17

+0

这是否解决了您的问题? – 2010-07-26 09:33:35

相关问题