1

I'm having a simple $inc that has also {upsert: true}. Meaning that it is supposed to create it if it doesn't exist.

I'm having daily more a than a million of such calls a day. It usually works ok. But from time to time I see that there were two documents created with the same parameters. Meaning that there is a problem with concurrency.

Is there something that I can do to make it concurrent?

According to the following stackoverflow answer it is supposed to be concurrent. How does the $inc modifier work with concurrent requests in mongodb?

The problem is that it isn't by me.

Elisha Sterngold
  • 2,324
  • 1
  • 16
  • 14

1 Answers1

1

While $inc is atomic, an upsert is not atomic when a document needs to be inserted.

So what you need to do is add a unique index to your collection that covers the fields you're upserting by and then handle the duplicate key exception to recover from unintended duplicates.

An example of this from this other answer on the topic:

var minute = utils.minute();
Monitor.update({ _id: minute }, { $inc: update }, { upsert: true }, function(err) {
    if (err) {
        if (err.code === 11000) {
            // Another upsert occurred during the upsert, try again. You could omit the
            // upsert option here if you don't ever delete docs while this is running.
            Monitor.update({ _id: minute }, { $inc: update }, { upsert: true },
                function(err) {
                    if (err) {
                        console.trace(err);
                    }
                });
        }
        else {
            console.trace(err);
        }
    }
});
JohnnyHK
  • 305,182
  • 66
  • 621
  • 471