我将MongoDB与NodeJS结合使用。因此,我用猫鼬。

我正在开发一个多人实时游戏。因此有时我会同时收到许多玩家的许多要求。

我可以通过说我有一个房屋收藏来简化它,如下所示:

{
    "_id" : 1,
    "items": [item1, item2, item3]
}


我有一个静态函数,在收到每个请求后调用:

house.statics.addItem = function(id, item, callback){
    var HouseModel = this;
    HouseModel.findById(id, function(err, house){
        if (err) throw err;
        //make some calculations such as:
        if (house.items.length < 4){
            HouseModel.findByIdAndUpdate(id, {$push: {items: item}}, cb);
        }
    });
}


在此示例中,我进行了编码,以使house文档永远不能超过4个项目。但是发生的事情是,当我同时接收到多个请求时,两个请求都两次执行了此功能,并且由于该请求是异步的,因此它们都会将一个新项目推送到items字段中,然后我的房子就有5个项目。

我做错了什么?将来如何避免这种行为?

最佳答案

是的,您需要更好地锁定houseModel,以指示addItem
正在处理。

问题是多个请求可以调用findById并看到相同的
house.items.length,然后每个都基于该(过时的)快照确定
可以再添加一项。原子性的nodejs边界是
打回来;在异步调用及其回调之间,其他请求可以运行。

一种简单的解决方法是不仅跟踪房屋中的物品数量,还跟踪
预期的addItem的数量。进入addItem时,将“
添加更多”计数,然后进行测试。

10-07 21:20