ishahak
ishahak

Reputation: 6795

MongoDB: no locking?

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

Answers (2)

Clement Amarnath
Clement Amarnath

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

freakish
freakish

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

Related Questions