Reputation: 2276
I have a issue of concurrent request, which modifies db.
What am I doing is. One request fetch data for user-1 , then calculate data for user-1 modified a field-1 in record, and save.
next request fetch data for user-1 , then calculate data for user-1 modified a field-1 in record, and save.
Both request operates simultaneously. so last request update the wrong data.
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;
}
We are getting both requests at the same time.
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
}
Upvotes: 1
Views: 201
Reputation: 9105
If you want to operate on each request simultaneously, I'd suggest to use Bluebird.map
where you can handle each request as you want, with concurrency, and a final result.
For example:
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
})
You may also be interested in Bluebird.join
where you could calculate, and join the resulting data for more than one promise.
Second example where you fetch same user twice in the same 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(() => {})
Upvotes: 1