Я создаю веб-приложение, которое будет обрабатывать много транзакций в секунду.Я использую Express Server с Node Js.Что касается базы данных, я использую Redis для хранения атрибутов пользователя, которые будут постоянно колебаться в зависимости от цены акций.Я использую MongoDB для хранения полупостоянных атрибутов, таких как конфигурация заказа, конфигурация пользователя и т. Д.,
Я попал в состояние гонки, когда несколько заказов, размещенных пользователем, обрабатываются одновременно, но только одинбыло бы приемлемо в качестве проверки атрибута Redis, который хранит поле, не позволил бы обе транзакции.
Другая проблема заключается в том, что моя логика приложения чередует вызовы чтения и записи Redis и MongoDB.Итак, как бы я решил проблему состояния гонки для обеих БД
. Я думаю о том, чтобы попытаться СМОТРЕТЬ и MULTI + EXEC на Redis, чтобы убедиться, что для данного пользователя одновременно выполняется только одна транзакция.Или я могу настроить очередь на узле / Redis, которая будет обрабатывать заказы один за другим.Я не уверен, какой подход правильный.Или как его реализовать.
Это все псевдокод.Логика приложения намного сложнее с несколькими условиями.Я чувствую, что вся моя логика приложения является критическим разделом (что я считаю плохим)
//The server receives a request from Client to place an Order
getAvailableMargin(user.username).then((margin) => { // REDIS call to fetch margin of user. This fluctuates a lot, so I store it in REDIS
if (margin > 0) {
const o = { // Prepare an order
user: user.username,
price: orderPrice,
symbol: symbol
}
const order = new Order(o);
order.save((err, o) => { // Create new Order in MongoDB
if (err) {
return next(err);
}
User.findByIdAndUpdate(user._id, {
$inc: {
balance: pl
}
}) // Update balance in MongoDB
decreaseMargin(user.username) // decrease margin of User in REDIS
);
}
});
Считайте, что маржа равна 1, и с каждым новым маржемным запасом уменьшается на 1.
Теперьесли два запроса получены одновременно, то в Redis маржа будет равна 1 для обоих запросов, что приведет к состоянию гонки.Кроме того, теперь в MongoDB будут открыты два ордера.Когда на самом деле в конце первого ордера маржа должна была стать 0, а второй ордер должен был быть отклонен.Другая проблема заключается в том, что мы теперь продвинулись и обновили баланс для Пользователя в MongoDB дважды, по одному на каждый ордер.
Ожидается, что один из ордеров не должен быть выполнен, и следует повторить попытку, проверивновое поле в Redis.И баланс пользователя также должен был обновляться только один раз.
По сути, мне нужно было бы реализовать наблюдение на Redis и MongoDB и каким-либо образом повторить транзакцию, если какие-либо из наблюдаемых полей / документов изменятся?Это вообще возможно?Или есть гораздо более простое решение, которое я мог бы упустить?