【问题标题】:Entity Framework - duplicates handling实体框架 - 重复处理
【发布时间】:2018-05-01 11:15:09
【问题描述】:

我使用 Entity Framework 6、C# 和 MySQL InnoDB 作为我们的数据库引擎。

我有以下代码“在重复更新时插入”一条记录:

public async Task AddHostIdToGroup(HostsToGroup hostToGroup)
{
    using (var context = new MaintDbContext())
    {
        HostsToGroup htg = context.HostsToGroup.SingleOrDefault(hs => hs.HostId == hostToGroup.HostId);

        if (htg != null)
        {
            htg.GroupId = hostToGroup.GroupId;
            await context.SaveChangesAsync();
        }

        else
        {
            context.HostsToGroup.Add(hostToGroup);
            await context.SaveChangesAsync();
        }
    }
}

insert on duplicate update 的代码本身看起来不错。

不过,在我们的生产服务器上,我偶尔会看到duplicate errors

我最初的想法是这是一个竞争条件问题。

我可以做些什么来防止这些错误,或者我应该如何处理它们?

【问题讨论】:

  • 我在 WCF 服务中遇到过类似的问题,有时会出现重复记录。而且我必须锁定 Add/Update 方法只能由 1 个线程使用。尝试为此方法或互斥锁添加锁
  • 你也可以使用lock来限制只有一次调用来执行更新或插入语句,但这可能会影响性能。
  • 它是什么样的系统?网络服务/网站? lock 语句不适用于这两种情况,当然也不能在async 方法中使用。只有在单个用户应用程序可能会触发对该方法的多次调用时,它才会有所帮助。
  • 显然我不会使用锁,这不是一个严肃的解决方案

标签: c# mysql entity-framework


【解决方案1】:

您的问题不一定是代码,而是触发该代码的原因。假设代码是由 ASP.net 应用程序按钮触发的,如果用户双击该按钮,那么它可能会同时发出两个请求,从而导致创建双重实体。

因此,要么修复您的前端/入口点以消除双重创建场景,将所有内容推送到允许您进行重复数据删除的同步服务/队列中,或者使用 Where 而不是 Single 并处理代码中的重复。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-20
    • 2011-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多