我如何锁定文档以读取值然后更新

时间:2019-04-22 14:18:04

标签: mongodb concurrency mongodb-query

在我的应用程序中,用户可以订阅事件。每个事件允许的最大参加人数。在预订活动时,我将用户的ID添加到活动文档中的数组。当数组的长度等于最大参与者数时,用户应添加到具有参与者待命的第二个数组中。

我担心的是,如果有许多并发预订,那么如果在另一预订已读取阵列的实际大小之后又写入用户预订,然后将用户添加到事件中,则该预订可能会被超额预订。

由于我是新手,所以不确定如何使用mongodb实施此操作。我想最好的事情是,如果我可以在阅读开始时锁定文档,而在写作结束时将其解锁。 我搜索了在mongodb上锁定文档的方法,但没有找到任何示例。也许我用错了术语。 我还发现了findAndModify,但没有暗示这种方法是否可以解决我的问题。

...

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
  }
);
...

如果有人可以引导我朝正确的方向或提供有关如何解决此问题的提示,那就太好了。

更新: 以下克里希纳·普拉萨德(Krishna Prasad)的答案向我澄清了findAndModify的使用,似乎可以解决我的问题。 出于好奇,如果有人可以举一个例子,对文档进行锁定,我将不胜感激。

最佳 马库斯

1 个答案:

答案 0 :(得分:0)

根据官方文档:

  
    

修改单个文档时,findAndModify和update()方法都会自动更新文档。有关这些方法的交互作用和操作顺序的更多详细信息,请参见原子性和事务。

  

链接:在下面的链接之前:https://docs.mongodb.com/manual/reference/command/findAndModify/#transactions

还要看看stackoverflow ans Is mongoDB's findAndModify "transaction-save"