Состояние гонки MongoDB на вставке во время нагрузочного теста

1

При выполнении нагрузочных тестов я иногда сталкиваюсь с ситуацией, когда этот код (упрощенный):

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

выдает ошибку, потому что операция вставки конфликтует с существующим документом - хотя я только что проверил, что с помощью findOne(). Оболочка Mongo показывает документ при приостановке перед вставкой().

Ошибка:

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. с помощью findAndModify с флагом Upsert
  3. с помощью Update with Replace and Upsert

Проблема с этими методами заключается в том, что 1 + 2 заменяет только некоторые поля, и я хочу заменить весь документ, а метод 3 заменяет весь документ, но _id конфликтует.

(Если применимо, я использую официальный драйвер С# версии 1.9.2.235)

Ценю вашу помощь.

  • 0
    Не могли бы вы понять, какую именно ошибку вы получаете и что в конечном итоге вы пытаетесь выполнить с помощью этого кода? Примеры документов также помогают. Похоже, вы должны просто попытаться вставить документ без проверки, как если бы документ существовал, вы получите уникальное нарушение ключа в _id, но трудно сказать с помощью предоставленной вами информации.
  • 0
    @wdberkeley - добавил больше деталей, спасибо.
Теги:
mongodb-.net-driver

1 ответ

0
Лучший ответ

Хорошо, если я правильно понимаю, вы хотите сделать следующее:

  1. Проверьте, существует ли документ с данным UniquePersonId
  2. Если это не так, вставьте документ с помощью этого UniquePersonId
  3. Если такой документ существует, ничего не делайте.

Ваш код попадает в двойную ключевую ошибку по той причине, по которой вы думаете, что она делает - другой поток вставляет тот же UniquePersonId между findOne и insert. Это хорошо - ошибка просто сообщает код, что какой-то другой процесс уже проделал свою работу. Уникальная ошибка нарушения индекса не является ошибкой в плохом смысле, что что-то не работает правильно. Это просто означает, что ваша операция недействительна из-за уникального ограничения, которое вы наложили. Я думаю (не зная больше о контексте этого), что вы можете запустить вставку и просто проглатывать уникальную ошибку индекса, если она встречается.

  • 0
    Так что это может быть что-то вроде: try {Insert ();} catch {} для достижения этой цели. Но что вы говорите, что нет лучшего способа решить это?
  • 0
    Какой лучший способ вы ожидаете существовать? Кажется, прекрасно для меня.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню