Node中有没有更好的方式来处理Mongo中的并发?
我正在开发一个API,我们发送从各种GET返回的单个资源的Last-Modified
date头。
当客户端在该资源上进行PUT / PATCH时,他们可以发送If-Unmodified-Since
报头,以确保他们只更新最新版本的资源。
支持这是一种痛苦,因为我希望我的应用程序能够响应以下用例:
- 您尝试更新的资源不存在(404)
- 您尝试更新的资源失败的先决条件(412)
- 处理请求时出错(500)
有没有更好的方式来做到这一点与Mongo,这不涉及到三个单独的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); }); });
你有太多的疑问,你可能知道。 这一般的stream程应该是:
- 按ID查找文档 – 如果没有find,给404
- 检查
if-unmodified-since
标题是否存在,并将其与文档的修改date进行比较。 问题412(如适用) - 如果允许,更新文档
所以,你的代码应该是这样的:
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); }); });