Nodejs中的并发请求处理
我有一个并发请求的问题,它修改数据库。
我在做什么。 一个请求获取用户1的数据,然后计算用户1修改的logging中的字段1的数据,并保存。
下一个请求获取用户1的数据,然后计算用户1修改的logging中的字段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 }
如果你想同时操作每个请求,我会build议使用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
感兴趣,可以计算出来,并将结果数据join一个以上的承诺。
第二个例子,你在相同的承诺中两次获取同一个用户:
//both are promises Bluebird.all([fetchUser1, fetchUser2]) .spread(function(user1, user2) { //check if should update return user1.delete !== user2.delete ? user.delete() : null }) .then(() => {})
Bluebird.spread文档