Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB update multiple documents

Schema:

{
    name: String,
    available: Boolean,
    for: String
}

there are "a":

{
    name: "a",
    available: true,
    for: ["b", "c"]
}

and "b":

{
    name: "b",
    available: true,
    for: ["a", "b]
}

if I update a.available = false, I should update b.available = false at the same time. how could I update two documents and make sure there would not has other process/thread getting "b" between the time when updating "a" and "b".

like image 555
Kevin Avatar asked Feb 21 '23 13:02

Kevin


2 Answers

MongoDB doesn't support atomic transactions. So if you need to make the first update "undo itself" if the second update fails, then you're out of luck.

However, in some limited cases, MongoDB does support isolated updates. The update isn't all or nothing, but MongoDB will guarantee that nobody else writes to the collection in the middle of your write.

A couple of major caveats:

  • The documents must all be in the same collection
  • The updates must all be specified in one query

Based on the example you've provided, your case might qualify.

Here is the documentation describing an isolated update.

Basically you'll want to issue the an update similar to the following to atomically set "available" to false when name is either "a" or "b":

db.blah.update({"name": {"$in": ["a", "b"]}, "$atomic": 1}, {"available": false});
like image 67
Sean Reilly Avatar answered Feb 23 '23 04:02

Sean Reilly


If you really need it, it may be possible to implement this logic on top of mongodb (in your application or better in a wrapper for the mongo driver).

You are asking for the isolation property. One way to achieve that is by using the MVCC pattern. This is really overkill but this is to give you an idea of what you could do if you really need both mongodb and some ACID properties.

A generic implementation of the MVCC pattern is described here. There is also a project on github for implementing this, but it is a java project.

You may also see this SO question and their answers. My present answer is just a summary of it.

like image 35
ascobol Avatar answered Feb 23 '23 04:02

ascobol