【问题标题】:Database access for concurrent API requests并发 API 请求的数据库访问
【发布时间】:2019-10-19 13:30:02
【问题描述】:

如何确保数据库调用对于并发 API 调用是异步的?

例如,我有一个表示池的模型。

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

我希望在任何给定时间,数据库中只有 1 个未满池。 所以我有类似的东西可以在 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}
        });
    }

}

当我同时向这个端点发送 10 个请求时,他们每个人都认为他们是第一个,然后创建一个新池。 所以我最终得到了新的 10 个池,我预计其中有 2 个完整(封闭)池,每个池 5 个用户。

有没有办法确保所有这些请求都按顺序执行?

也许顺序是一个坏主意。但总的来说,我正在寻找一种方法来保持数据库的状态始终有效。

Nodejs 适合这个吗?

任何指向正确方向的指针将不胜感激。

【问题讨论】:

  • 我的 2 美分:也许您可以通过将池存储在 Node 的范围内来破解它,但是您的代码无法轻松分发(如果您部署在簇)。对于顺序读/写,我认为 Mongo 不允许读取锁定,如果你扩展你的数据库,最终你会遇到同样的问题。根据您需要此系统的目的,您可以之后处理池一致性,方法是触发一个脚本(轮询?),该脚本将检查是否有多个池打开并在情况下合并它们出现。

标签: javascript node.js rest mongoose


【解决方案1】:

解决方案是使用互斥锁来同步关键块。
我用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
    });
}          

【讨论】:

    猜你喜欢
    • 2018-07-10
    • 1970-01-01
    • 1970-01-01
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-08
    相关资源
    最近更新 更多