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文档