Node JS + Redis + MongoDB Web应用程序中的竞争条件

时间:2019-04-03 08:17:07

标签: node.js mongodb redis race-condition node-redis

当同时处理一个用户下的多个订单时,我遇到了竞争问题,但是只有一个可以作为对存储保证金的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上实现监视,并且如果任何监视的字段/文档发生更改,以某种方式重试事务?那有可能吗?还是我可能会缺少一个更简单的解决方案?

0 个答案:

没有答案