Update 2 different collections simultaneously

Viewed 350

I have two models defined like this:

var OrganizationSchema = new mongoose.Schema({
    users: [mongoose.Schema.Types.ObjectId]
});

and

var UserSchema = new mongoose.Schema({
    organizations: [mongoose.Schema.types.ObjectId]
});

When a user want to join an organization I need to update both the organization collection and the user collection. I want to know what is the best way to achieve this ? Is it worth considering the case when one update request fail ? I'm currently doing something like this (where organization is a collection instance of the model Organization):

User.findByIdAndUpdate(req.userSession.userId, { $push: { organizations: organization.id } }, function (err){
    if (err)
    {
        // server error
        console.log(err);
    }
    else
    {
        organization.users.push(req.userSession.userId);
        organization.save(function (err){
            if (err)
            {
                // server error we need to cancel 
                User.findByIdAndUpdate(req.userSession.userId, { $pull: { organizations: organization.id } }, function (err){
                    if (err)
                    {
                        // we got a problem one collection updated and not the other one !!
                        console.log(err);
                    }
                });
            }
            else
            {
                 // success
            }
        });
      }
    });

The problem is: if my second update method fail I will end up with one collection updated and not the other ? Is there a way to make sure they are both updated ?

1 Answers

Well firstly, I would stay clear of that design. I would either reference or embed user in organisations and the other way around, not both of them at same time, so I wouldn't have problems like this(which happens every-time you duplicate data).

MongoDB doesn't have support for simultaneous updates, or transactions. So you are left to manage this in your code.

So yes, if the second update fails, then as you wrote your code you have to rollback, and if the rollback fails, you have to retry till it succeeds(though with exponential backoff probably). Keep in mind that might intefer with other requests(another user tries to save the same thing simultaneously). To handle that you have to give a unique to each entry in the array.

Related