MongoDB C#并发问题与upsert

时间:2019-05-20 08:43:52

标签: c# mongodb mongodb-.net-driver

我有一个非常简单的方法来对集合中的条目进行升序:

    public void UpsertEntry(string collectionName, Entry entry)
    {
        var collection = GetCollection(collectionName);
        var filter = Builders<Entry>.Filter.Eq(x => x.Key, entry.Key);
        var update = Builders<Entry>.Update
            .SetOnInsert(x => x.Id, ObjectId.GenerateNewId())
            .SetOnInsert(x => x.Key, entry.Key)
            .Set(x => x.LastUpdated, DateTime.Now)
            .Set(x => x.Data, entry.Data)
            .Inc(x => x.Version, 1);

        var result = collection.UpdateOne(filter, update, new UpdateOptions
        {
            IsUpsert = true
        });
    }

该集合在Key上具有唯一索引。

我在Parallel.For循环中调用UpsertEntry方法

        Parallel.For(0, 100, i =>
        {
            entry.Key = $"key+{i}";
            UpsertEntry(coll, entry);
        });

我希望插入100条记录,但是我收到了E11000 duplicate key error collection: TestDB.test::c7 index: key_1 dup key: { : "key+1" }。为什么会遇到并发问题?我的代码有什么问题?

2 个答案:

答案 0 :(得分:0)

错误消息是说已经有一个空记录。换句话说,这意味着您已经拥有一个具有相同键的集合

相关文档:

  

如果文档中唯一索引的字段没有值   索引,索引将为此文档存储一个空值。因为   唯一的约束,MongoDB将只允许一个文档   缺少索引字段。如果有多个文档而没有   索引字段的值或缺少索引字段的索引   构建将因重复的密钥错误而失败。

     

您可以将唯一约束与稀疏索引结合使用以进行过滤   唯一索引中的这些空值,避免出现错误。

唯一索引

  

稀疏索引仅包含具有索引字段的文档条目,即使

     
    

索引字段包含一个空值。

  

换句话说,稀疏索引可以处理多个都为空值的文档。

答案 1 :(得分:0)

我解决了这个问题,它与驱动程序本身无关。我没有注意到我正在重用类Entry的相同实例:-)