У меня есть простая коллекция под названием Ledger со следующей схемой
Ledger: {
account: String,
amount: Number // actually an integer
}
У меня есть функция, которая дебетует счет на основании остатка на нем:
const debit = async (account_to_be_debited, amount_to_be_debited) => {
let transactions = await Ledger.find({ account: account_to_be_debited })
let balance = transactions.reduce((accumulated_balance, transaction) => {
accumulated_balance += transaction.amount
return accumulated_balance
}, 0)
if (balance < amount_to_be_debited) {
throw new Error('insufficient funds')
}
let new_transaction = await Ledger.create({ account: account_to_be_debited, amount: -amount_to_be_debited })
return new_transaction._id
}
Теперь я хочу иметь возможность сделать что-то подобное в асинхронной среде:
// the first debit
debit('account_1', 100).then(id => console.log(id))
// another debit
debit('account_1', 200).then(id => console.log(id))
Меня беспокоит то, что, если две операции по дебету происходят одновременно, существует риск двойного расходования, поскольку обе операции по дебету будут проверяться на идентичный баланс.Это не было бы проблемой, если бы вместо этого я ждал завершения одной дебетовой транзакции перед выполнением следующей
let debit_1 = await debit('account_1', 100)
let debit_2 = await debit('account_1', 200)
Мне известно, что с выпуском mongodb 4.0 я могу использовать транзакции, но я не уверен, что mongodb выполняет транзакции синхронно.Если это так, то я могу быть уверен, что каждая последующая транзакция будет считывать изменения, отраженные самой последней зафиксированной транзакцией, и что чтение между транзакциями не может происходить одновременно, потому что транзакции не могут происходить одновременно.
ИтакМой вопрос: подходят ли транзакции mongodb для моего случая использования, особенно для смягчения состояния гонки, которое я описал выше?
Если нет, каковы возможные пути решения этой проблемы?Я пишу это приложение на узле js, и в настоящее время я использую mongoose для моделирования и взаимодействия с набором реплик mongodb.
Любая помощь очень ценится.Спасибо.