C# 如何正确处理EF并发错误?

C# 如何正确处理EF并发错误?,c#,concurrency,entity-framework-6,C#,Concurrency,Entity Framework 6,我已经找到了很多关于并发错误的主题,但它们似乎都是关于保留数据库或客户端值的,但我需要某种混合解决方案——从数据库重新加载初始值并重新尝试更改它,而不仅仅是用客户端值替换存储值 问题描述 假设我有一个数据库,其中包含3个表Users、Orders和OrderSummaries示例,以简化问题解释 每个用户都有自己的订单,但订单汇总在OrderSummaries表中。创建新订单时,新记录将添加到Orders表中,并在OrderSummaries表中更新摘要记录 所以,当两个或多个用户同时添加新订单

我已经找到了很多关于并发错误的主题,但它们似乎都是关于保留数据库或客户端值的,但我需要某种混合解决方案——从数据库重新加载初始值并重新尝试更改它,而不仅仅是用客户端值替换存储值

问题描述

假设我有一个数据库,其中包含3个表Users、Orders和OrderSummaries示例,以简化问题解释

每个用户都有自己的订单,但订单汇总在OrderSummaries表中。创建新订单时,新记录将添加到Orders表中,并在OrderSummaries表中更新摘要记录

所以,当两个或多个用户同时添加新订单记录时,更新OrderSummaries表时可能会出现并发错误

发生并发错误时,我不想保留存储或客户机值,我发现这是针对此错误最建议的解决方案,但我想重复上述OrderSummareRecord分配,但使用数据库中的当前OrderSummareRecord值

我的想法是将此代码包装成一个循环,如下所示:


目前我无法验证此方法是否有效。。。也许SO的一些EF专家可以看看并验证这是否有效,或者建议在这种情况下处理并发性的更好/正确的方法?

只需使用事务即可。它们是为这个用例而设计的。在SERIALIZABLE下,您可以保证零竞争条件。@usr感谢您提供的信息。你有一些好的信息链接吗?如何使用实体框架?或者你可以自己简单解释一下,作为对这篇文章的回答?
    //db -> DbContext instance
    var OrderSummariesRecord = db.OrderSummaries.FirstOrDefault(..filter expresion..);
    OrderSummariesRecord.Value += NewOrderRecord.Value;
    db.Entry(OrderSummariesRecord).State = System.Data.Entity.EntityState.Modified;
    db.SaveChanges();
Boolean saved = false;
while (!saved)
{
    try
    {
        var OrderSummariesRecord = db.OrderSummaries.FirstOrDefault(..filter expresion..);

        //would this be enough to make sure, that in the next iterations 
        //(after some concurrency errors has happened) the newest values from the
        //database are acquired?
        db.Refresh(RefreshMode.StoreWins, OrderSummariesRecord);

        OrderSummariesRecord.Value += NewOrderRecord.Value;
        db.Entry(OrderSummariesRecord).State = System.Data.Entity.EntityState.Modified;
        db.SaveChanges();

        saved=true;
    }
    catch (DbUpdateConcurrencyException ex)
    {
        //some logging here
    }
    catch (Exception exc)
    {
        //Don't repeat - there's some other error
        saved=true;
    }
}