MongoDb upsert 的 C# 并发问题

MongoDb C# concurrency issues with upsert

我有一个非常简单的方法来更新集合中的条目:

    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" }。为什么我会遇到并发问题?我的代码有什么问题?

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

相关文档:

If a document does not have a value for the indexed field in a unique index, the index will store a null value for this document. Because of the unique constraint, MongoDB will only permit one document that lacks the indexed field. If there is more than one document without a value for the indexed field or is missing the indexed field, the index build will fail with a duplicate key error.

You can combine the unique constraint with the sparse index to filter these null values from the unique index and avoid the error.

唯一索引

Sparse indexes only contain entries for documents that have the indexed field, even if

the index field contains a null value.

换句话说,稀疏索引可以用于多个文档都具有空值。

我解决了,和驱动本身没有关系。我没有注意到我是 re-using class 条目的同一个实例:-)