代码之家  ›  专栏  ›  技术社区  ›  Vitor Durante

如何处理EF核心上的并发性

  •  2
  • Vitor Durante  · 技术社区  · 6 年前

    我有一个方法可以在数据库中搜索一个实体,如果它不存在,我会尝试创建它。举个例子:

    public async Country FindOrCreate(string name)
    {
        var country = _context.Countries.FirstOrDefault(p => p.Name == name);
    
        if (country != null)
            return country;
    
        country = new Country
        {
            Name = name
        };
    
        _context.Countries.Add(country);
        _context.SaveChanges();
    
        return country;
    }
    

    问题是:后台调用有几个任务 FindOrCreate 同时地。我通过创建一个唯一索引来防止插入重复项,但会发生以下情况,导致不需要的异常:

    1. 任务A试图找到国家却失败了
    2. 任务B试图找到国家,但失败了
    3. 任务A试图创建国家并成功
    4. 任务B试图创建国家,但失败了

    处理这些并发场景的适当方法是什么?我应该使用C代码处理锁吗?还是应该设置一个事务处理?蒂亚

    1 回复  |  直到 6 年前
        1
  •  3
  •   Alex Buyny    6 年前

    使用唯一索引在DB级别处理并发性是这里的正确方法。唯一性指数将保证国家的唯一性,无论什么。

    不要费心锁定C代码,只要有一台以上的服务器在运行你的应用程序,它就不会工作(现在很可能)。在这种情况下,交易是 tricky business 所以我不会麻烦你的。

    如何处理这些异常:

    如果创建国家/地区时任务失败,请捕获异常并重试。如果您由于某种原因未能再次获得国家,请记录异常并失败。