In my app the users can subscribe to an event. There is a max number of participants allowed on each event. On booking an event i add the id of the user to an array within the event document. When the length of the array equals the max number of participants the user should instead get added to a second array with stand by participants.
My concern is that if there are many concurrent bookings the event could get overbooked if the write of one booking happens after another booking has read the actual size of the array and then itself adds the user to the event.
As i'm a newbee im unsure on how to implement this with mongodb. The best thing i guess would be if i could lock the document when the reading starts and unlock it when the writing has finished.
I searched for locking a document on mongodb but found no examples. Perhaps i used the wrong terms.
I also found findAndModify
but no hint if this method would solve my problem.
...
const module = await Modules.findOne({ _id: args.moduleId });
if (!module.participantsIds ||
module.participantsIds.length < module.maxParticipants) {
updateAction = {
$addToSet: { "participantsIds": userId }
};
} else {
updateAction = {
$addToSet: {
"standByParticipants": {
"participantId": userId, "timeStamp": new Date()
}
}
};
}
await Modules.update(
//query
{
_id: args.moduleId
},
//update
updateAction,
//options
{
"multi": false,
"upsert": false
}
);
...
It would be great if someone could lead me in the right direction or give a hint on how to go about this problem.
Update: the answer of krishna Prasad below clarified to me the use of findAndModify and seems to solve my problem. Just out of curiosity i'd appreciate if someone could give an example with a lock on the document, if this is even possible.
Best Markus