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".
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:
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});
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With