更新嵌套文档mongo。并发问题

时间:2014-07-21 04:06:18

标签: node.js mongodb mongoose

我正在努力解决Mongoose中一个看似基本的问题。

我有一个看起来像这样的方法:

changeStateOnIncident: function(req, res, next) {
  Incident.findOneQ({ _id: req.params.id })
  .then(function(incident) {
    if (!incident) { return next(new restify.ResourceNotFoundError("Incident with id " + req.params.id + " not found.")) }
    return incident.addStateChange(req.body)
    .then(function(savedState) {
      return res.json(201, savedState);
    })
    .then(function() {
      var alertOrders = _.map(incident.alertees, function(alertee) {
        return alertee.createAndSendAlert(req.body)
      })
      return Q.allSettled(alertOrders)
      .then(function(results) {
        return incident.save();
      })
    })
  })
  .fail(function(err) {
    return next(new restify.InvalidContentError(JSON.stringify(err)))
  })
},

对于createAndSendAlert和addStateChange,其定义为here

我在这里要做的是:

  1. 查找与传入的ID匹配的事件。
  2. 将状态事件添加到状态更改数组中。
  3. 将新添加的更改事件返回给用户。
  4. 对于事件中的每个提醒者,循环并向该提醒警报列表添加警报,即SMS请求的结果。
  5. 保存该事件。
  6. 不幸的是,我现在这样做的方式是并发写入失败。假设我发送了两个

    {
      _id: "53cc87d0feeb4302007eadbe",
      alertees: [
        {
          _id: "eJ65nfJh_g",
          alerts: [
            {
              "_id": "53cc87d1feeb4302007eadc1",
              "created_at": "2014-07-21T03:24:01.304Z",
              "response": "Sent",
              "state": "First state change",
              "updated_at": "2014-07-21T03:24:06.802Z"
            },
            {
              "_id": "53cc87d2feeb4302007eadc5",
              "created_at": "2014-07-21T03:24:02.348Z",
              "response": "Sent",
              "state": "Emergency",
              "updated_at": "2014-07-21T03:24:06.802Z"
            },
            {
              "_id": "53cc87d6feeb4302007eadcc",
              "response": "Sent"
              "state": "Ended",
            }
          ]
        }
      ],
    
      states: [
        {
          _id: "53cc87d1feeb4302007eadbf",
          state: "First state change"
        },
        {
          _id: "53cc87d1feeb4302007eadc2",
          state: "Second state change"
        },
        {
          _id: "53cc87d2feeb4302007eadc4",
          state: "Third state change"
        },
        {
          _id: "53cc87d6feeb4302007eadcb",
          state: "Fourth state change"
        }
      ]
    }
    

    我认为发生的事情是,如果我发送两个状态A和B.并且A的短信响应在B之前回来,它可能使B试图修改的文件无效。如果状态更改发送得太近,我将丢失对子文档的更改。

    有什么想法吗?我怎么能改写这个?也许使用更新方法?

0 个答案:

没有答案