node.js - Nodejs 中的并发请求处理

标签 node.js concurrency

我遇到了并发请求的问题,它修改了数据库。

我在做什么。 一次请求获取 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;
}

enter image description here

我们同时收到这两个请求。

  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(() => {})

Bluebird.spread documentation

关于node.js - Nodejs 中的并发请求处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37433240/

相关文章:

javascript - 通过标签名称获取元素的子元素长度

node.js - node_redis : using client. forEach 内多

node.js - 我可以在 node.js 中指定 RabbitMQ 凭据吗?

c# - 通过消息分片ID实现多线程消费者

scala - 测试依赖于 future 的 AKKA Actor

java对象序列化 - 线程安全?

javascript - Node.js Mongoose 的麻烦

javascript - '类型错误: undefined is not a function' error when using 'flickrnode' API

c++ - 在线程之间共享数据时如何从不变性中获益?

使用 join() 的 Java 多线程程序在计算相邻数字之和时给出了错误的结果