node.js - How to prevent race conditions in a distributed nodejs web servers architecture backed by mongodb -
here' s description of problem:
- i have x web workers written in nodejs (express.js) behind load ballancer. these workers write data mongodb (mongoose.js)
 - i've setup endpoint y such @ point in middleware chain of handler i'm doing following logic: if requesting user exists in database, fetch it, update fields store back. if doesn't exist, insert in mongo.
 
note! i'm unable use mongoose's findandupdateone() - atomic - due domain specific logic, ie. if user exists update value, else insert value.
- the problem is, quite often, 2 requests same user (who doesn't yet exist in db) hit 2 different workers. when user processing middleware kicks in, both workers determine user doesn't exist , attempt insert update it. naturally causes errors, eg. validation errors: i've setup unique email per user validation , others.
 
how can prevent this?
you can use $set , $setoninsert update operators achieve that.
from mongodb $setoninsert docs:
if update operation upsert: true results in insert of document, $setoninsert assigns specified values fields in document. if update operation not result in insert, $setoninsert nothing.
and
if db.collection.update() upsert: true had found matching document, mongodb performs update, applying $set operation ignoring $setoninsert operation.
so, should trick:
var = date.now();  users.update({ _id: 1 }, {   $set:         { updatedat: },   $setoninsert: { createdat: } }, {upsert: true}, function(err, doc) {    // resultant doc available here  })      
Comments
Post a Comment