当同时处理一个用户下的多个订单时,我遇到了竞争问题,但是只有一个可以作为对存储保证金的Redis属性的支票而不能进行这两项交易的条件。
另一个问题是我的应用程序逻辑交错了Redis和MongoDB的读写访问。那么我将如何解决两个数据库之间的竞争条件
我正在考虑尝试在Redis上进行WATCH和MULTI + EXEC,以确保给定用户一次仅发生一次事务。或者,我可以在Node / 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中的新保证金来重试。而且用户的余额也应该只更新一次。
基本上,我是否需要在Redis和MongoDB上实现监视,并且如果任何监视的字段/文档发生更改,以某种方式重试事务?那有可能吗?还是我可能会缺少一个更简单的解决方案?