2012-03-02 33 views
4

我正在尋找在使用實體框架時處理併發的最佳方式。最簡單和最值得推薦的(也堆棧)解決方案說明如下: http://msdn.microsoft.com/en-us/library/bb399228.aspx 它看起來像:在實體框架中處理併發性

try 
{ 
    // Try to save changes, which may cause a conflict. 
    int num = context.SaveChanges(); 
    Console.WriteLine("No conflicts. " + 
    num.ToString() + " updates saved."); 
} 
catch (OptimisticConcurrencyException) 
{ 
    // Resolve the concurrency conflict by refreshing the 
    // object context before re-saving changes. 
    context.Refresh(RefreshMode.ClientWins, orders); 

    // Save changes. 
    context.SaveChanges(); 
    Console.WriteLine("OptimisticConcurrencyException " 
    + "handled and changes saved"); 
} 

但是否足夠?如果Refresh()和第二個SaveChanges()之間的內容發生變化,該怎麼辦?將會有未捕獲的OptimisticConcurrencyException?

編輯2:

我認爲這將是最終的解決方案:

int savesCounter = 100; 
    Boolean saveSuccess = false; 
    while (!saveSuccess && savesCounter > 0) 
    { 
     savesCounter--; 
     try 
     { 
      // Try to save changes, which may cause a conflict. 
      int num = context.SaveChanges(); 
      saveSuccess = true; 
      Console.WriteLine("Save success. " + num.ToString() + " updates saved."); 
     } 
     catch (OptimisticConcurrencyException) 
     { 
      // Resolve the concurrency conflict by refreshing the 
      // object context before re-saving changes. 
      Console.WriteLine("OptimisticConcurrencyException, refreshing context."); 
      context.Refresh(RefreshMode.ClientWins, orders); 

     } 
    } 

我不知道,如果Iunderstand如何刷新()的作品。它是否刷新整個上下文?如果是,爲什麼需要額外的參數(實體對象)?還是隻刷新指定的對象? 例如,在這種情況下,我應該爲刷新()第二個參數進行傳遞:

Order dbOrder = dbContext.Orders.Where(x => x.ID == orderID); 
dbOrder.Name = "new name"; 
//here whole the code written above to save changes 

應該dbOrder?

+2

+1這是我第一次閱讀時對這個例子的反對意見!一般來說,在異常處理程序中執行「風險」操作(saveChanges)是不好的做法。我很驚訝在官方文檔中看到這一點。 – 2012-03-02 14:05:10

+1

Re:你的改變,看起來不錯。如果說100次重試無法補救這種情況,我會小心謹慎,這可能會打破循環。總是很難調試以永無止境的循環結束的問題。即使他們不應該發生;-) – 2012-03-02 14:42:32

+1

嘗試在這個鏈接的方法它使用不同的方式來處理concurreny,這可能是更可靠的評價遵循: - http://www.asp.net/mvc/tutorials /工具入門與 - EF-使用-MVC /處理併發與 - 的實體框架式-AN-ASP淨MVC應用程序 – 2012-03-16 03:38:19

回答

4

是,即使第二保存,如果可能引起OptimisticConcurrencyException - 就像你說的 - 這是Refresh()SaveChanges()之間變化。

給出的例子只是一個非常簡單的重試邏輯,如果您需要重試多次或以更復雜的方式解決衝突,最好創建一個將重試n次的循環,而不是嵌套try /趕上更多的這個單一的水平。