【发布时间】:2017-03-21 04:25:20
【问题描述】:
我有一个 Node.js 服务器,它必须处理 6 个并发请求。 每个请求都会从 MonogDB 数据库中读取一个文档,然后对其进行修改。
所以,当我们同时发送 6 个请求时,它们都读取相同的数据项并对其进行修改,但我希望第一个请求修改的值应该由第二个请求读取,然后它应该能够进一步修改它等等开。
例如, 我有一个名为 x 的数据项,初始值为“a”。 第一个请求将其修改为“ab”。所以,第二个请求现在应该是“ab”而不是“a”。但它总是读取“a”,因为它们是同时出现的。
我尝试应用信号量、互斥锁、async.series、async.waterfall、sleep 和 promise,但没有任何效果。可能我没有正确使用它们。那么,应该如何使用它们来同步处理这些并发请求呢?
或者还有其他方法吗?我们可以用时间戳排序协议做点什么吗?如果是,那么我如何在 Node.js 中应用它?
这是我要为这些并发请求运行的代码-
app.get('/urltest', function (req, res) {
var q=require('url').parse(req.url,true).query;
var s=q.s;
MongoClient.connect(url, function(err, db) {
if(err)
throw err;
db.collection( 'Comp' ).find({no:2}).snapshot().forEach(
function (elem) {
db.collection( 'Comp' ).findAndModify (
{ no : elem.no },
[['no', 1]],
{ $set : { age:elem.age+s } }, {new:true},
function( err, result ) {
if ( err ) console.log( err);
console.log("after update: "+result.value.age);
res.end("success");
}
);
});
});
});
我在这里同时发送诸如 http://192.168.197.140:8081/urltest?s=b、http://192.168.197.140:8081/urltest?s=c、http://192.168.197.140:8081/urltest?s=d 等请求。
现在,它们可以按任何顺序运行。但我希望附加所有“b”、“c”、“d”等。因此每个的输出应该看起来有点像 - 'ab'、'abc'、'abcd' 等等。
但我得到的输出是-'ab'、'ac'、'ad'。
我应该如何使用 Promise 来确保这些请求以同步方式执行?
【问题讨论】:
-
如果大约同时有 6 个请求到达,你怎么知道应该先去哪一个,第二个,第三个,等等……?如果您需要有关您尝试过的某些特定代码解决方案的帮助,那么您必须向我们展示您尝试过的代码并解释您尝试它时发生的情况。让一项操作等待另一项操作完成并不难,但我们必须看看您到底想做什么(查看实际代码并了解实际算法)才能知道如何为您编写代码。
-
您也可以创建一个访问队列。如果没有人在队列中访问特定数据项,那么它只会获取该项目。如果一个操作已经在进行中,那么下一个请求会进入队列,并在前一个请求完成后得到服务。使用 Promise 可以很容易地做到这一点。但是,要知道建议什么代码,我们需要查看您正在尝试执行的特定代码,并了解您如何知道哪些请求需要像这样序列化。
-
@jfriend00 我已经更新了问题并包含了我想要同步运行的基本代码。我尝试过使用 Promises,但它们也不起作用。对于访问队列,我尝试将这些传入请求存储在一个数组中,然后一个一个地访问它,但这也不起作用。那么,您能否详细说明我应该如何准确编写代码来实现我的结果?
标签: javascript node.js mongodb concurrency