Как предотвратить «Данная транзакция № 1 не совпадает с текущими транзакциями» с транзакциями Mongoose? массовые () транзакции? - PullRequest
0 голосов
/ 21 октября 2019

Я использую Mongoose для доступа к моей базе данных. Мне нужно использовать транзакции для атомарного вставки-обновления. В 95% случаев моя транзакция работает нормально, но в 5% случаев отображается ошибка:

«Данная транзакция № 1 не соответствует ни одной из выполняемых транзакций»

Это очень сложновоспроизвести эту ошибку, поэтому я действительно хочу понять, откуда она исходит, чтобы избавиться от нее. Я не мог найти очень четкое объяснение об этом типе поведения.

Я пытался использовать ключевые слова async / await в различных функциях. Я не знаю, выполняется ли операция вовремя или слишком рано.

Вот код, который я использую:

export const createMany = async function (req, res, next) {
  if (!isIterable(req.body)) {
    res.status(400).send('Wrong format of body')
    return
  }
  if (req.body.length === 0) {
    res.status(400).send('The body is well formed (an array) but empty')
    return
  }

  const session = await mongoose.startSession()
  session.startTransaction()
  try {
    const packageBundle = await Package.create(req.body, { session })
    const options = []
    for (const key in packageBundle) {
      if (Object.prototype.hasOwnProperty.call(packageBundle, key)) {
        options.push({
          updateOne: {
            filter: { _id: packageBundle[key].id },
            update: {
              $set: {
                custom_id_string: 'CAB' + packageBundle[key].custom_id.toLocaleString('en-US', {
                  minimumIntegerDigits: 14,
                  useGrouping: false
                })
              },
              upsert: true
            }
          }
        })
      }
    }
    await Package.bulkWrite(
      options,
      { session }
    )
    for (const key in packageBundle) {
      if (Object.prototype.hasOwnProperty.call(packageBundle, key)) {
        packageBundle[key].custom_id_string = 'CAB' + packageBundle[key].custom_id.toLocaleString('en-US', {
          minimumIntegerDigits: 14,
          useGrouping: false
        })
      }
    }
    res.status(201).json(packageBundle)
    await session.commitTransaction()
  } catch (error) {
    res.status(500).end()
    await session.abortTransaction()
    throw error
  } finally {
    session.endSession()
  }
}

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

...