Reputation: 6795
I searched a lot but could not find a clear solution, although my scenario is super standard. In the code below I'm checking if ID exists. Then:
If ID doesn't exist, a record is inserted with count=1.
Otherwise, count is increased by 1
req.db.collection('names_table').count({_id: name}, function (e, result) {
if (e) { return next(e); }
if (result === 0) { //name not yet exists
var new_name = { "_id": name, count:1; };
db.collection('names_table').insert(new_name, function (e) {
if (e) { return next(e); }
debug('name ' + name + ' created successfully');
res.redirect('back');
});
} else {
debug('increasing name ' + name + ' to ' + result);
var update_name = { '$inc': { "count": 1 } };
db.collection('names_table').update({_id: player_id}, update_name, function (e) {
if (e) { return next(e); }
debug('Updated!');
res.redirect('back');
});
}
});
How can I make sure that between {decision that the ID doesn't exist} and {new id is inserted}, no other thread will come and repeat the same logic and also try to insert after testing if exist?
Upvotes: 0
Views: 51
Reputation: 5476
Try this, it might be solving your issue
_id on a document is unique by default, so no need of checking it whether the id exists and insert a record or update a record.
Update query used together with upsert will help you handling the scenario of inserting a record if _id is not exists and updating the record if _id is already there.
db.names_table.update( { _id: "name", $inc: { count: 1 }},{ upsert: true })
Pass the real value for _id
More info on Update and Upsert
Upvotes: 1
Reputation: 56587
Well, if _id
is unique (as it should be) then parallel inserts will fail for all but one caller. Now if you are worried that in case of failure you should increment the counter, then you additionally have to call update
in case of insert
failure.
All of that can be combined into one update
with upsert: true
though.
Upvotes: 2