如何使用 mongoDB/mongoose 并行执行读/写文档 [英] How to read/write a document in parallel execution with mongoDB/mongoose

查看:87
本文介绍了如何使用 mongoDB/mongoose 并行执行读/写文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将 MongoDB 与 NodeJS 一起使用.因此我使用猫鼬.

我正在开发一款多人实时游戏.所以我有时会同时收到很多玩家的很多请求.

我可以简单地说,我有一个房子收藏,看起来像这样:

<代码>{_id":1,"items": [item1, item2, item3]}

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

house.statics.addItem = function(id, item, callback){var HouseModel = this;HouseModel.findById(id, function(err, house){如果(错误)抛出错误;//进行一些计算,例如:如果(house.items.length <4){HouseModel.findByIdAndUpdate(id, {$push: {items: item}}, cb);}});}

在此示例中,我进行了编码,以便 house 文档永远不会超过 4 个项目.但是发生的情况是,当我同时收到多个请求时,这个函数会被两个请求执行两次,而且由于它是异步的,它们都将一个新项目推送到项目字段,然后我家有 5 个项目.

我做错了什么?我怎样才能在未来避免这种行为?

解决方案

是的,你需要更好地锁定 houseModel,以表明一个 addItem正在进行中.

问题是多个请求可以调用findById,看到的都是一样的house.items.length,然后根据那个(过时的)快照确定可以再添加一项.nodejs 的原子性边界是打回来;在异步调用与其回调之间,可以运行其他请求.

一个简单的解决方法是不仅要跟踪房子里的物品数量,还要跟踪预期的 addItems 的数量也是如此.在进入 addItem 时,撞上想要添加更多"计数,并进行测试.

I'm using MongoDB with NodeJS. Therefore I use mongoose.

I'm developing a multi player real time game. So I receive many requests from many players sometimes at the very same time.

I can simplify it by saying that I have a house collection, that looks like this:

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

I have a static function, called after each request is received:

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);
        }
    });
}

In this example, I coded so that the house document can never have more than 4 items. But what happens is that when I receive several request at the very same time, this function is executed twice by both requests and since it is asynchronous, they both push a new item to the items field and then my house has 5 items.

I am doing something wrong? How can I avoid that behavior in the future?

解决方案

yes, you need better locking on the houseModel, to indicate that an addItem is in progress.

The problem is that multiple requests can call findById and see the same house.items.length, then each determine based on that (outdated) snapshot that it is ok to add one more item. The nodejs boundary of atomicity is the callback; between an async call and its callback, other requests can run.

One easy fix is to track not just the number of items in the house but the number of intended addItems as well. On entry into addItem, bump the "want to add more" count, and test that.

这篇关于如何使用 mongoDB/mongoose 并行执行读/写文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆