Одновременное обновление в mongodb

Я использовал этот код на стороне сервера node.js для обновления нескольких встроенных документов.

        DetailerItemGroupModel.find({
                "_id": itemGroupId
            })
            .forEach(function (doc) {
                doc.Products.forEach(function (ch) {
                    //do something before update
                });
                DetailerItemGroupModel.save(doc);
            });

У меня такой сценарий: Клиент A и B выполняют метод GET http, чтобы получить одни и те же документы в одно и то же время, затем клиент B сначала выполняет обновление (вызов сервера, который запускает приведенный выше код), а затем клиент A выполняет обновление.

Поэтому я хочу, чтобы когда клиент A выполнял HTTP-метод UPDATE для сервера, он должен был получить данные, которые были последними (в этом случае документ был обновлен B), я имею в виду, как отменить запрос клиента A и вернуть неверный запрос на сообщить, что данные, которые клиент А собирается обновить, были изменены другим клиентом. Любой способ реализовать это?

Я читал о «__v», но не уверен, когда клиенты A и B отправляют запрос на одновременное обновление одного и того же документа. Работает ли он с forEach (), я меняю код на этот

         DetailerItemGroupModel.find({
                "_id": itemGroupId,
                "__v" : {document version}
            })
            .forEach(function (doc) {
                doc.Products.forEach(function (ch) {
                    //do some thing before update
                });
                DetailerItemGroupModel.save(doc);
            });

@JohnnyHK не могли бы вы взглянуть еще раз!

Jed 01.05.2018 04:41

@Jed, почему ты не используешь обещание?

divine 01.05.2018 05:46

@divine, что ты имеешь в виду? использовать обещание на стороне клиента для обработки ответа BadRequest от сервера? Можете ли вы уточнить?

Jed 01.05.2018 05:55

я говорю об этом mongoosejs.com/docs/promises.html

divine 01.05.2018 06:18

Как это было возможно, я просто хочу реализовать правило, которое позволяет обновлять только при совпадении __v. Но мне интересно, как, если 2 запроса поступят в ближайшее время, этот код все равно вернет документ DetailerItemGroupModel.find ({"_id": itemGroupId, "__v": {версия документа}})

Jed 01.05.2018 06:40
Стоит ли изучать 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
5
95
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Идея в том, что вы хотите, чтобы ваше «Сохранить» работало только с той версией, которая у вас есть (которая должна быть последней).

Использование .save здесь не поможет.

Вы можете использовать одну из двух функций:

Обновить.findOneAndUpdate

Идея в том, что вам нужно выполнить поиск и сохранить за одну атомарную операцию. И в объекте условий вы не только отправляете _id, но также отправляете __v, который является идентификатором версии. (Что-то похожее на пример ниже)

this.update({_id: document._id, __v: document.__v}, {$set: document, $inc: {__v: 1}}, result.cb(cb, function(updateResult) {
    ...
});

Допустим, вы читаете версию 10, теперь вы готовы ее обновить (сохранить). Он будет работать только в том случае, если он найдет документ с определенным идентификатором и версией. Если тем временем база данных получит более новую версию (версия 11), ваше обновление не удастся.

Кстати, у MongoDb теперь есть транзакции, вы можете захотеть изучить это, потому что транзакция B заставит ваш код ждать, пока транзакция A завершит свою атомарную операцию, что было бы лучшей моделью, чем выполнение обновления и сбой, а затем повторная попытка .. .

Спасибо за ваше предложение, я не знаю, почему __v просто атомарное увеличение с помощью некоторого метода, такого как .save (), Кстати, когда я хочу использовать шаблон __v mongodb, это означает, что я должен отправить $ inc {__ v: 1} при выполнении .Update (...), без разницы, братан!

Jed 12.05.2018 06:39

Я думаю, что сохранение приращений Mongoose происходит автоматически, но не обновляется. Я помню, что мне пришлось самому добавить $ inc, чтобы все работало должным образом.

Ralph 12.05.2018 16:22

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