Friday, 9 June 2017

How to update mongodb array item without race condition?

I have an update query that proved to be subject to a race condition, but I don't really know why.

Let's say I have a stuff collection in mongodb. I'm using numeric ids for the sake of clarity.

stuff: {
  _id: 123
  elements: [
    {
      _id: 456,
      value: 'foo',
    },
    {
      _id: 789,
      value: 'bar'
    },
  ]
}

Now I want to update the value on the element 456 that lives under the stuff 123.

I thought this was ok (I'm using mongoose, hence the Stuff class):

Stuff.update(
  {
    _id: 123,
    'elements._id': 456
  },
  {
    $set: {
      'elements.$': {
        _id: 456,
        value: 'foobar',
      }
    }
  }
)

This query, however, seems to be subject to a race condition. I can't really explain why, but I could prove that firing that request in parallel would mess up my data; in particular if I try to update both elements 456 and 789 at the same time.

  • Is there a comprehensive reason of why this causes trouble ?
  • Is there a way to fix the query so it becomes concurrent-proof ?

Thanks !

PS: in case that's of any relevance, I'm using Mongoose



via aherve

No comments:

Post a Comment