Синхронизированное обновление документов с использованием Mongoose - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть сервер API nodejs, развернутый в кластере Kubernetes. Пользователи могут отправлять заявки на аукционы. Чтобы ставка не перекрывала другую, необходима некоторая синхронизация.

Я вижу следующее для входящей ставки:

  • начать транзакцию, которая считывает текущую ставку, сравнивает ее с входящей ставкой и обновляет запись
  • создать агрегат, который делает то же, что и выше

Я не знаю, куда идти. Я также понимаю, что вам нужно заблокировать документ с помощью IX или X.

Для СУБД вы должны создать транзакцию, которая блокирует запись и выпускает ее после обновления, но я не знаю, как она работает для MongoDB.

Product.findById(productId)
  .then(productmatch => {
    if (productmatch.currentPrice > price) throw Error('no go')

    const bid = new Bid({
      price,
      date: Date.now(),
      user: user._id
    })
    return Product.findByIdAndUpdate(productId, {
        $push: {
          bids: bid
        },
        currentPrice: price,
        currentUser: user,
        currentBid: bid
      }, {
        new: true
      })
      .then(product => {
        if (!product) throw Error(`no go`)

        return bid._id.toString()
      })
  })

1 Ответ

0 голосов
/ 16 ноября 2018

После небольшого исследования я нашел это решение, однако я не знаю, надежно ли оно на 100%, но я полагаю, что этот метод заблокирует документ и не позволит другим потокам читать документ между операциями запроса и обновления.

var query = {
    _id: productId,
    closed: false,
    currentPrice: {
      $lt: price
    }
  },
  update = {
    $push: {
      bids: bid
    },
    currentPrice: price,
    currentUser: user,
    currentBid: bid
  },
  options = {
    new: true
  };
return Product.findOneAndUpdate(query, update, options)
  .then(product => {
    if (!product) throw Error(`no product found with id ${productId}`)
    return bid._id.toString()
  })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...