Я использую 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()
}
}
Я ожидаю, что мой код будет добавлен в базу данных иобновите входные пакеты атомарным способом, чтобы не было нестабильного состояния базы данных. Это отлично работает для основной части, но я должен быть уверен, что эта ошибка больше не отображается.