Is there a way to perform a set of non-atomic actions on MongoDB server (using the Ruby driver) as an single atomic action? What I need is basically a lock on certain object/collection.
2 Answers
Because you can perform atomic operations on single documents, there are ways to simulate what you want. See this article:
http://kylebanker.com/blog/2010/06/07/mongodb-inventory-transactions/
And for some of the principles behind the ideas there, see this one:
http://www.eaipatterns.com/docs/IEEE_Software_Design_2PC.pdf

- 4,359
- 23
- 18
-
The thing is that this works well if something "goes wrong", i.e. an error occurs. However, I'm more worried about cases where there's nothing wrong, no error, the data are fine from app's point of view, but they're wrong for user. And as we're deploying to Heroku, I can't even be sure that if user sends us two requests, that these two requests will be handled in the same order they as were sent (each can be assigned to different dyno, each may be processed upon invalid, but technically correct/possible dataset). Unlikely, not critical, but freaks me out :) – PJK Nov 18 '10 at 22:30
There's no way to do it in the Ruby driver because there's no way to do it in MongoDB. Mongo only supports single-document atomic operations. So basically an insert, update or delete of a single document is done atomically, but not operations across multiple documents.
You might be able to fake a transaction by attempting a manual "roll-back" if an error occurs. A roll-back in this case would be to replace any changes with the previous values. But that's going to manual and not have the ACID guarantees that you would get from most SQL servers.

- 2,681
- 22
- 21