MongoDB added support for multi-document ACID transactions in version 4.0 in 2018 and extended that support for distributed multi-document ACID transactions in version 4.2 in 2019. MongoDB's document model allows related data to be stored together in a single document.
To answer the actual question directly: "Why are nosql databases not acid compliant" is because they weren't designed to be. ACID is a lot of work and requries lots of resources in the machine, but even Google are being forced to go back to ACID and SQL!
The short answer is that ACID, an acronym for “Atomicity, Consistency, Isolation, and Durability,” is a set of principles that ensure database transactions are processed reliably. When any data storage system upholds those principles, it is said to be ACID compliant.
MongoDB, has always supported ACID transactions in a single document and, when leveraging the document model appropriately, many applications don't need ACID guarantees across multiple documents.
It's actually not correct that MongoDB is not ACID-compliant. On the contrary, MongoDB is ACID-compilant at the document level.
Any update to a single document is
What MongoDB doesn't have is transactions -- that is, multiple-document updates that can be rolled back and are ACID-compliant.
Note that you can build transactions on top of the ACID-compliant updates to a single document, by using two-phase commit.
One thing you lose with MongoDB is multi-collection (table) transactions. Atomic modifiers in MongoDB can only work against a single document.
If you need to remove an item from inventory and add it to someone's order at the same time - you can't. Unless those two things - inventory and orders - exist in the same document (which they probably do not).
I encountered this very same issue in an application I am working on and had two possible solutions to choose from:
1) Structure your documents as best you can and use atomic modifiers as best you can and for the remaining bit, use a background process to cleanup records that may be out of sync. For example, I remove items from inventory and add them to a reservedInventory array of the same document using atomic modifiers.
This lets me always know that items are NOT available in the inventory (because they are reserved by a customer). When the customer check's out, I then remove the items from the reservedInventory. Its not a standard transaction and since the customer could abandon the cart, I need some background process to go through and find abandoned carts and move the reserved inventory back into the available inventory pool.
This is obviously less than ideal, but its the only part of a large application where mongodb does not fit the need perfectly. Plus, it works flawlessly thus far. This may not be possible for many scenarios, but because of the document structure I am using, it fits well.
2) Use a transactional database in conjunction with MongoDB. It is common to use MySQL to provide transactions for the things that absolutely need them while letting MongoDB (or any other NoSQL) do what it does best.
If my solution from #1 does not work in the long run, I will investigate further into combining MongoDB with MySQL but for now #1 suits my needs well.
A good explanation is contained in "Starbucks Does Not Use Two Phase Commit".
It's not about NoSQL databases, but it does illustrate the point that sometimes you can afford to lose a transaction or have your database in an inconsistent state temporarily.
I wouldn't consider it to be something that needs to be "fixed". The fix is to use an ACID-compliant relational database. You choose a NoSQL alternative when its behavior meets your application requirements.
I think other people gave good answers already. However i would like to add that there are ACID NOSQL DBs (like http://ravendb.net/ ). So it is not only decision NOSQL - no ACID vs Relational with ACID....
As of MongoDB v4.0, multi-document ACID transactions are to be supported. Through snapshot isolation, transactions will provide a globally consistent view of data, and enforce all-or-nothing execution to maintain data integrity.
They feel like transactions from the relational world, e.g.:
with client.start_session() as s:
s.start_transaction()
try:
collection.insert_one(doc1, session=s)
collection.insert_one(doc2, session=s)
s.commit_transaction()
except Exception:
s.abort_transaction()
See https://www.mongodb.com/blog/post/multi-document-transactions-in-mongodb
"won't save correctly" could mean:
By default MongoDB does not save your changes to the drive immediately. So there is a possibility that you tell a user "update is successful", power outage happens and the update is lost. MongoDB provides options to control level of update "durability". It can wait for the other replica(s) to receive this update (in memory), wait for the write to happen to the local journal file, etc.
There is no easy "atomic" updates to multiple collections and even multiple documents in the same collection. It's not a problem in most cases because it can be circumvented with Two Phase Commit, or restructuring your schema so updates are made to a single document. See this question: Document Databases: Redundant data, references, etc. (MongoDB specifically)
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