我遇到了并发请求的问题,它修改了数据库。
我在做什么。 一次请求获取 user-1 的数据,然后计算 user-1 修改记录中 field-1 的数据,并保存。
下一个请求获取 user-1 的数据,然后计算 user-1 修改记录中 field-1 的数据,并保存。
两个请求同时运行。所以最后一个请求更新了错误的数据。
function calculate() {
var needUpdate = false;
user = new UserLib(user_id);
var old_config = user.config;
if (old_config[req.id]) {
old_config[req.id].value = 0;
needUpdate = true;
}
if (req.delete == void(0) || req.delete == false) {
delete req.delete;
old_config[req.id].value = old_config[req.id].value + 1;
needUpdate = true;
}
if (needUpdate) {
return user.save();
}
return true;
}
我们同时收到这两个请求。
var express = require('express');
var app = express();
app.get('/update', function(req, res) {
res.writeHead(200, {
'Content-Type': 'text/html'
});
calculate(req);
function calculate(req) {
var needUpdate = false;
user = new UserLib(user_id);
var old_config = user.config;
if (old_config[req.id]) {
old_config[req.id].value = 0;
needUpdate = true;
}
if (req.delete == void(0) || req.delete == false) {
delete req.delete;
old_config[req.id].value = old_config[req.id].value + 1;
needUpdate = true;
}
if (needUpdate) {
user.save();
}
}
res.end('Done');
});
first reuest with following parameter {
user_id: 1,
id: 1,
value: 5,
delete: false
}
Anothere request with follwing parmter {
user_id: 1,
id: 1,
delete: true
}
最佳答案
如果您想同时处理每个请求,我建议使用 Bluebird.map
,您可以根据需要处理每个请求,并具有并发性和最终结果。
例如:
let users = ['foo', 'bar']; //fetching users you want
Bluebird.map(users, (user) => {
return user.calculate()
.then((res) => res.shouldUpdate ? user.save() : Promise.resolve())
}, {concurrency: 2})
.then((results) => {
//results is an array with both resolved promises from below
})
您可能还对 Bluebird.join
感兴趣您可以在其中计算并连接多个 promise 的结果数据。
第二个示例,您在同一个 promise 中两次获取同一用户:
//both are promises
Bluebird.all([fetchUser1, fetchUser2])
.spread(function(user1, user2) {
//check if should update
return user1.delete !== user2.delete ? user.delete() : null
})
.then(() => {})
关于node.js - Nodejs 中的并发请求处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37433240/