处理Entity Framework中的并发性

时间:2012-03-02 13:16:43

标签: entity-framework concurrency optimistic-concurrency

我正在寻找使用Entity Framework时处理并发的最佳方法。这里描述了最简单,最推荐(也是堆栈)的解决方案: 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);

        }
    }

我不确定是否了解Refresh()的工作原理。它是否刷新整个背景?如果是,为什么需要额外的参数(实体对象)?或者只刷新指定的对象? 例如,在这种情况下应该作为Refresh()第二个参数传递什么:

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

应该是dbOrder吗?

1 个答案:

答案 0 :(得分:4)

是的,即使是第二次保存,如果 - 正如您所说 - 在Refresh()SaveChanges()之间发生了某些变化,即使是OptimisticConcurrencyException。

给出的示例只是一个非常简单的重试逻辑,如果您需要多次重试或以更复杂的方式解决冲突,您最好创建一个循环,重试n次,而不是嵌套try / catch超过这个单一水平。