简体   繁体   English

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

[英]MongoDB race condition on insert during load test

When performing load tests, I sometimes encounter a situation when this code (simplified): 在执行负载测试时,有时会遇到以下情况(以下代码):

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

throws an error, because the insert operation conflicts with an existing document - even though I just checked that using findOne(). 抛出错误,因为插入操作与现有文档冲突-即使我只是使用findOne()进行了检查。 Mongo shell shows the document when pausing before the insert(). 当在insert()之前暂停时,Mongo Shell将显示文档。

The error is: 错误是:

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) }).

The unique index is: 唯一索引是:

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

This smells like a race condition, and I'm trying to find the right way to resolve this: 这闻起来像是竞争状况,我正在尝试找到解决此问题的正确方法:

  1. using $setOnInsert 使用$ setOnInsert
  2. using findAndModify with Upsert flag 使用带有Upsert标志的findAndModify
  3. using Update with Replace and Upsert 使用带有替换和更新的更新

The problem with those methods is that 1+2 only replace certain fields and I want to replace the entire document, and method 3 replaces an entire document but the _id is conflicted. 这些方法的问题在于1 + 2仅替换了某些字段,我想替换整个文档,而方法3替换了整个文档,但是_id冲突。

(If relevant, I'm using the official C# driver version 1.9.2.235) (如果相关,我正在使用官方的C#驱动程序版本1.9.2.235)

Appreciate your help. 感谢您的帮助。

OK, if I am understanding correctly, you want to do the following: 好的,如果我的理解正确,您想执行以下操作:

  1. Check if a document with a given UniquePersonId exists 检查是否存在具有给定UniquePersonId的文档
  2. If it doesn't, insert a document with that UniquePersonId 如果不是,请插入具有该UniquePersonId的文档
  3. If such a document does exist, do nothing. 如果存在这样的文档,则什么也不做。

Your code hits the duplicate key error for the reason you think it does - another thread inserts the same UniquePersonId between the findOne and the insert . 您的代码由于您认为这样做的原因而导致重复键错误-另一个线程在findOneinsert之间插入相同的UniquePersonId。 That's fine - the error just tells the code that some other process has done its work already. 很好-错误只是告诉代码其他进程已经完成了工作。 The unique index violation error isn't an error in the bad sense that something's not working right. 唯一的索引违规错误并不是从某种意义上不能正常工作的错误中得出的错误。 It's just letting you know your operation is invalid because of the unique constraint that you imposed. 这只是让您知道操作由于您施加的唯一约束而无效。 I think (without knowing more about the context of this) that you can run the insert and just swallow the unique index error if it occurs. 我认为(无需进一步了解上下文),您可以运行插入操作,并在出现唯一索引错误时将其吞下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM