Доступ к базе данных для одновременных запросов API - PullRequest
1 голос
/ 04 июня 2019

Как можно гарантировать, что вызовы базы данных являются асинхронными для одновременных вызовов 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 запросов одновременно на эту конечную точку, каждый из них думает, что они 1-й, а затем создают новый пул.Таким образом, я получаю 10 новых пулов, в которых ожидалось 2 полных (закрытых) пула по 5 пользователей в каждом.

Есть ли способ обеспечить последовательное выполнение всех этих запросов?

Может быть, последовательноплохая идеяНо в целом я ищу способ, чтобы состояние БД всегда было действительным.

Хорошо ли для этого Nodejs?

Будем весьма благодарны за любые указатели в правильном направлении.

1 Ответ

0 голосов
/ 29 июня 2019

Решением было использование мьютекса для синхронизации критического блока.
Я использовал Асинхронный замок

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
    });
}          
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...