如何确保数据库调用与并发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对此有用吗?
任何指向正确方向的指针将不胜感激。
答案 0 :(得分:0)
解决方案是使用互斥锁来同步关键块。
我使用了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
});
}