简体   繁体   English

对并发API请求的数据库访问

[英]Database access for concurrent API requests

How can one ensure that the database calls are asynchronous for concurrent API calls? 如何确保数据库调用与并发API调用异步?

For example, I have this model that represents a pool. 例如,我有一个代表游泳池的模型。

{
    limit: number e.g 5
    isOpen: boolean // will close when users.length == limit
    users: []
}

I want that at any given time, there's only 1 non-full pool in the DB. 我希望在任何给定时间,数据库中只有1个非全池。 So I have something like this that runs on an API call. 因此,我可以在API调用上运行类似的内容。

let openPool = model.findOne({isOpen: true});
if(!openPool){

    //create a new pool
    model.insert({
        limit: 5,
        users: [currentuser]
        isFull: false
    });
}else{

    //add the current user to existing open pool
    model.update({
        users: {$push: {currentuser}}
    });

    //close pool if full
    if(model.users.length == model.users.limit){
        model.update({
            isOpen: {$set: false}
        });
    }

}

When I send 10 requests at the same time to this endpoint, each of them thinks they are the 1st and then create a new pool. 当我同时向该端点发送10个请求时,每个人都认为它们是第一个,然后创建一个新池。 So I end up with new 10 pools where I expected 2 full (closed) pools of 5 users each. 因此,我最终得到了新的10个池,在其中我希望有2个完整(封闭)池,每个池有5个用户。

Is there a way to ensure that all these requests execute sequentially? 有没有办法确保所有这些请求都按顺序执行?

Maybe sequentially is a bad idea. 也许顺序地是个坏主意。 But overall, I'm looking for a way to keep the state of the DB always be valid. 但是总的来说,我正在寻找一种方法来保持数据库状态始终有效。

Is Nodejs good for this? Nodejs对此有好处吗?

Any pointers to the right direction will be much appreciated. 任何指向正确方向的指针将不胜感激。

The solution was to use a mutex to synchronize the critical block. 解决方案是使用互斥锁来同步关键块。
I used async-lock 我用了异步锁

var AsyncLock = require('async-lock');
var lock = new AsyncLock();

requestHandler(){
    return new Promise(async (resolve,reject) => {
        lock.acquire('key', async () => {
           let openPool = await model.findOne({isOpen: true});
           if(!openPool){

           //create a new pool
           await model.insert({
               limit: 5,
               users: [currentuser]
               isFull: false
           });
        }else{
            //add the current user to existing open pool
            await model.update({
                users: {$push: {currentuser}}
            });

            //close pool if full
            if(model.users.length == model.users.limit){
                model.update({
                    isOpen: {$set: false}
                });
            }
        }

        return resolve(true);
    }).then(() => {
        //lock released
    });
}          

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM