C# mongo是否将文档锁定在UpdateOneAsync调用的范围内?

C# mongo是否将文档锁定在UpdateOneAsync调用的范围内?,c#,.net,mongodb,mongodb-query,.net-core,C#,.net,Mongodb,Mongodb Query,.net Core,即使在并发环境中,我也需要使用特定值使文档的字段仅可更新一次。例如,Id为123456的文档有一个(字符串)字段SomeField,初始值等于null。我想出了一个类似这样的代码: public async Task<bool> SetSomeField(string id, string value) { var updateResult = await GetCollection().UpdateOneAsync( x =>

即使在并发环境中,我也需要使用特定值使文档的字段仅可更新一次。例如,Id为
123456
的文档有一个(字符串)字段
SomeField
,初始值等于
null
。我想出了一个类似这样的代码:

public async Task<bool> SetSomeField(string id, string value)
{
    var updateResult = await GetCollection().UpdateOneAsync(
        x =>
            x.Id == id &&
            (!x.SomeField.HasValue || x.SomeField.Value == value),
        Builders<SomeDocument>
            .Update
            .Set("SomeField", value));

    return updateResult.MatchedCount != 0;
}
public async Task SetSomeField(字符串id,字符串值)
{
var updateResult=await GetCollection().UpdateOneAsync(
x=>
x、 Id==Id&&
(!x.SomeField.HasValue | | x.SomeField.Value==Value),
建设者
使现代化
.Set(“SomeField”,value));
返回updateResult.MatchedCount!=0;
}
如果两个线程尝试调用此方法,例如
await SetSomeField(“123456”,“value1”)
await SetSomeField(“123456”,“value2”)
一个调用应设置
SomeField
的值并返回
true
,另一个调用应返回
false
。重要的是,所有后续调用继续返回与第一次相同的值

换句话说,我需要在并发环境中使这个方法幂等

这段代码似乎工作正常,但我不确定是否在满足条件后,mongo会以某种方式锁定文档,以确保它不会被同时更新

该解决方案有效吗,还是需要一些外部锁定机制


如果问题缺少任何必要的细节,请发表评论,我很乐意提供。

您可能需要使用global来更新云数据,否则当两个线程尝试调用它时,它们不会干扰。

mongo在更新时锁定整个集合,您的代码中不需要任何锁。您可以阅读更多有关它的信息。它可能会在更新时锁定集合,但这种锁定是否会从检查条件的那一刻起持续到更新结束的那一刻?“一个调用应该设置SomeField的值并返回true,另一个调用应该返回false。”-为什么?如果您实际查看任何连续(并且它们将连续发生)更新的写入结果,其中一个将显示“修改”计数,而另一个不会。这是
$set
和其他类似操作符的一点魔力,因为它们实际上不“修改”任何实际处于该状态的内容。考虑<代码> $Inc< /Cult>运算符,它只是在“找到的状态”中增加一个值。所以我认为你是在防范一些不存在的东西。@NeilLunn你是什么意思,为什么?因为需要按照我所述的方法工作。@Nikola.Lukovic请注意WiredTiger存储引擎(自2015年12月发布MongoDB 3.2以来的默认设置)具有文档级并发性,并支持许多不同的功能,例如压缩。有关更多详细信息,请参阅。如果您实际查看任何连续更新(它们将连续发生)的写入结果,其中一个将显示“修改”计数,而另一个则不会。这是$set和其他类似操作符的一点魔力,因为它们实际上不会“修改”状态中的任何内容。考虑$Inc运算符,它只增加一个值“在它被发现的状态”。