0

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?

1
  • Using upsert you can create or update atomically. But in case of multiple simultaneous requests, the last write wins.
    – s.d
    Commented Jun 23, 2016 at 7:54

2 Answers 2

2

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.

1

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

2
  • Thank you, looks promising! I think you have a typo: probably meant for "so no need of"
    – ishahak
    Commented Jun 23, 2016 at 7:23
  • @ishahak - Thank you and Corrected the typo. Commented Jun 23, 2016 at 7:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.