我正在构建一个Web应用程序,它将每秒处理许多事务。我正在将Express Server与Node Js一起使用。在数据库方面,我正在使用Redis存储用户的属性,该属性将根据股票价格而持续波动。我正在使用MongoDB来存储半永久属性,例如订单配置,用户配置等,
当同时处理一个用户下的多个订单时,我遇到了竞争问题,但是只有一个可以作为对存储保证金的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余量将为1,从而导致竞争状况。此外,由于这一结果,现在将在MongoDB中打开两个订单。实际上,在第一个订单末尾时,边距应为0,而第二个订单应已被拒绝。 另一个问题是,我们现在继续进行,并两次更新了MongoDB中用户的余额,每个订单一个。
期望不应该执行订单之一,而应该通过检查Redis中的新保证金来重试。用户的余额也应该只更新一次。
基本上,我是否需要在Redis和MongoDB上实现监视 并且如果任何受监视的字段/文档发生更改,则以某种方式重试事务? 那有可能吗?还是我可能会缺少一个更简单的解决方案?