负载测试期间插入的MongoDB竞争条件

时间:2014-11-12 13:04:41

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

执行负载测试时,我有时遇到这种代码(简化)的情况:

var person = Persons.findOne();
if(person == null){
         Persons.insert(newDocument);
}

抛出错误,因为插入操作与现有文档冲突 - 即使我只是使用findOne()检查它。 Mongo shell在insert()之前暂停时显示文档。

错误是:

WriteConcern detected an error ''. (Response was { "ok" : 1, "code" : 11000, "err" : "insertDocument :: caused by :: 11000 E11000 duplicate key error index: MainDB.Persons.$Person UniquePersonID dup key: { : \"BOT 878611 141152\" }", "n" : NumberLong(0) }).

唯一索引是:

{ v: 1, name: "Person UniquePersonID", key: { UniquePersonID : 1 }, unique: true, ns: "MainDB.Persons", sparse: true, dropDups: true, background: true }

这闻起来就像一场竞争条件,我正试图找到解决这个问题的正确方法:

  1. 使用$ setOnInsert
  2. 将upAndModify与Upsert标志一起使用
  3. 使用Update with Replace and Upsert
  4. 这些方法的问题是1 + 2只替换某些字段,我想替换整个文档,方法3替换整个文档,但_id是冲突的。

    (如果相关,我使用的是官方C#驱动程序版本1.9.2.235)

    感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

好的,如果我理解正确,你想要做以下事情:

  1. 检查具有给定UniquePersonId的文档是否存在
  2. 如果没有,请插入带有UniquePersonId的文档
  3. 如果确实存在此类文件,则不执行任何操作。
  4. 您的代码因您认为的原因而遇到重复键错误 - 另一个线程在findOneinsert之间插入相同的UniquePersonId。这没关系 - 错误只是告诉代码其他一些进程已经完成了它的工作。唯一索引违规错误并不是错误的错误,即某些东西无法正常工作。它只是让您知道您的操作无效,因为您施加了独特的约束。我认为(不知道更多关于此的上下文)你可以运行插入并只是吞下唯一索引错误。