是否有更好的方法来处理Node中Mongodb的并发性?

时间:2014-02-12 00:54:52

标签: javascript node.js mongodb

我正在开发一个API,我们为各种GET返回的各个资源发送Last-Modified日期标题。

当客户端在该资源上进行PUT / PATCH时,他们可以发送If-Unmodified-Since标头以确保它们仅更新资源的最新版本。

支持这是一种痛苦,因为我希望我的应用程序响应以下用例:

  • 您尝试更新的资源不存在(404)
  • 您尝试更新的资源未通过前提条件(412)
  • 处理请求(500)
  • 时出错

有没有更好的方法使用Mongo执行此操作,不涉及进行3次单独的Mongo数据库调用以捕获可能的用例并返回相应的响应?

我想清理一下:

// the callback the handler is expecting from the model method below

callback(err, preconditionFailed, wasUpdatedBool)

// model method

var orders = this.db.client({ collection: 'orders' });
var query = { _id: this.db.toBSON(this.request.params.id) };

// does the order exist?
orders.findOne(query, function(err, doc) {
  if(err) {
    return callback(err);
  }

  if(!doc) {
    return callback(null, null, false);
  }

  // are you updating the most recent version of the doc?
  var ifUnModifiedSince = new Date(self.request.headers['if-unmodified-since']).getTime();

  if(ifUnModifiedSince) {
    query.lastModified = { $lte: ifUnModifiedSince };

    orders.findOne(query, function(err, doc) {
      if(err) {
        return callback(err);
      }

      if(!doc) {
        return callback(null, true);
      }

      //attempt to update
      orders.update(query, payload, function(err, result) {
        if(err) {
          return callback(err);
        }

        if(!result) {
          return callback(null, null, false);
        }

        return callback(null, null, result);
      });
    });
  }

  //attempt to update
  orders.update(query, payload, function(err, result) {
    if(err) {
      return callback(err);
    }

    if(!result) {
      return callback(null, null, false);
    }

    callback(null, null, result);
  });
});

1 个答案:

答案 0 :(得分:0)

您可能知道的查询太多了。一般的流程应该是:

  1. 按ID查找文档 - 如果找不到,请提供404
  2. 检查是否存在if-unmodified-since标题,并将其与文档的修改日期进行比较。问题412(如适用)
  3. 如果允许,请更新文档
  4. 所以,你的代码应该是这样的:

    var orders = this.db.client({ collection: 'orders' });
        var query = { _id: this.db.toBSON(this.request.params.id) };
        orders.findOne(query, function(err, order) {
        if(err) {
            return callback(err); // Should throw a 500
        }
        if(!order) {
            return callback(404);
        }
        if(self.request.headers['if-unmodified-since']) {
            var ifUnModifiedSince = new Date(self.request.headers['if-unmodified-since']).getTime();
            if(order.lastModified.getTime() > ifUnModifiedSince) {
                return callback(412); // Should throw a 412
            }
        }
        // Now do the update
        orders.update(query, payload, function(err, result) {
            if(err) {
              return callback(err);
            }
             if(!result) {
              return callback(null, null, false);
            }
             return callback(null, null, result);
        });
    });