Состояние гонки NodeJS DB

Я использую NodeJS с Express для создания простого api отдыха. Мой рабочий процесс:

  1. Я передаю объект через POST URI
  2. Я хочу сохранить это в БД. Если он находится в БД, я хочу увеличить счетчик того, сколько раз мы пытались сохранить объект.

Мой код для сохранения такой:

await collection.updateOne({
      // match all the properties
    }, {
      $inc: {
        'encountered': 1
      }
    }, {
      upsert: true,
    });

Однако это создает состояние гонки, если я сделаю несколько одновременных вызовов одновременно ... Например, если я сделаю запрос POST 5 раз одновременно, я могу получить два результата:

один раз встречалось: 3x второй раз встретилось: 2x

Я предполагаю, что первая вставка провела поиск в БД, не нашла элемент и была подготовлена ​​для вставки, в то время как вторая вставка получила время потока, не нашла элемента и также была подготовлена ​​для вставки. Затем срабатывала первая вставка, увеличивалась несколько раз, а затем срабатывала вторая вставка и увеличивалась несколько раз.

Как мне с этим справиться? Глобальная переменная пытается имитировать синглтон ..? Я все еще не уверен, что это будет потокобезопасно ... Я не против худшей производительности, но мне нужно, чтобы записи в БД были абсолютно поточно-безопасными / атомарными, т.е. поиск и обновление считались атомарной операцией.

Обновлено: в качестве альтернативы я был бы рад не принимать никаких вызовов POST (т.е. блокировать операцию POST), пока мой предыдущий вызов не был полностью разрешен ..? Я не уверен, как правильно решить эту проблему с помощью NodeJS.

Edit2: Я также пробовал db.collection.createIndex, который затем не выполняет запись. Боюсь, что при повторной попытке этой неудачной записи я столкнусь с той же проблемой.

upsert должен быть атомарным - в этом смысл его использования вместо отдельного поиска и вставки. Итак, пока выполняется первый запрос, на эту коллекцию на мгновение накладывается блокировка до тех пор, пока запись не будет обновлена ​​или вставлена. Это работа базы данных, а не ваша, блокируя запросы. Если вы используете соответствующие функции в базе данных, база данных должна справиться с этим за вас. Я вообще не эксперт по параллелизму mongodb, но я думаю, что весь смысл $inc и upsert заключается именно в том, чтобы решить эту проблему параллелизма внутри базы данных, поэтому вам не нужно.
jfriend00 30.10.2018 23:05

Вы просто предполагаете, что у вас может быть проблема с параллелизмом? Или вы действительно тестировали и определили проблему параллелизма?

jfriend00 30.10.2018 23:05

@ jfriend00 Я протестировал все локально, и он отлично работает, но как только я запустил его в производство, где я могу получить даже 20-30 запросов одновременно, я увидел, что несколько идентичных элементов сохраняются в БД => Я пришел к вывод, что это проблема параллелизма, которая, как я ожидал, исходила из фона Java. Но поскольку в NodeJS нет «синхронизированного», я не знаю, как к этому подойти.

halpdoge 30.10.2018 23:09

Хорошо, тогда ищите места, где вы неправильно используете встроенные функции параллелизма в mongodb, вместо того, чтобы пытаться создать свой собственный элемент управления параллелизмом поверх БД. Вы должны позволить базе данных управлять этим за вас.

jfriend00 30.10.2018 23:11
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
33
0

Другие вопросы по теме