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