MongoDB supports multi-document ACID transactions as of version 4.0, even across replica sets and sharded clusters. The document model allows small collections of data to be stored together in a single document which, combined with atomic document updates, obviates the need for many of the cases that transactions were designed for in the relational database model. Nonetheless, there are numerous cases where true multi-document, multi-collection MongoDB transactions are just the tool for the job.
What are transactions?
Transactions are groups of database reads or writes that need to all succeed or all fail together. Imagine you were building a function to transfer money from one account to another. If you successfully take money from the source account, but never credit it to the destination, you have a serious accounting problem! You’d have just as big a problem (if not bigger) if you instead credited the destination, but never took money out of the source to cover it. These two writes have to either both happen, or both not happen, to keep our system sane.
This is the kind of problem that transactions were invented to solve: we tell the database we’re doing a transaction, and it keeps track of every update that it makes along the way. If the connection breaks before the transaction is complete, or if any command in the transaction fails, then the database rolls back (undoes) all of the changes it had written in the course of the transaction.
The downside of using a transaction is that the database has to do a lot of extra work to keep track of the transaction, and it has to “lock” the involved resources. That means other clients trying to get or update data might be stuck waiting for the transaction to complete, affecting application latency and ultimately user experience. Protecting transactions this way is critical in systems that rely on coordinated updates in this way.
What is ACID, and why does it matter?
ACID stands for Atomicity, Consistency, Isolation, and Durability. In order to formally guarantee the validity of a transaction, it is required to exhibit these four characteristics.
Atomicity guarantees that all of the commands that make up the transaction are treated as a single unit, and succeed, or fail, together.
Consistency guarantees that changes made within a transaction are consistent with constraints in effect on the database (like uniqueness of a value for a given key in documents in a collection).
Isolation guarantees that concurrently executed transactions do not affect each other’s outcomes – that
Durability guarantees that once the database has told the client it has written the data, that data has in fact been written to a backing store and will persist even in the case of a system failure.
The ACID characteristics of transactions are what allow developers to perform complex coordinated updates, and sleep well at night knowing that their data is consistent and safely stored. In MongoDB, single-document updates are ACID compliant, and because documents lend themselves to grouping larger chunks of data into one place than tabular structures do, a well-designed document schema allows you to work without the need for multi-document transactions in most cases.
When you do need multi-document ACID transactions, MongoDB transactions work across your cluster and operate the way you’d expect. There is performance overhead to using transactions in such a distributed system, so you’ll want to be mindful of your resource constraints and performance goals.
How do transactions work in MongoDB?
MongoDB transactions work similarly to transactions in other databases. To use a transaction, you start a MongoDB session through the driver, and then you use that session to execute your group of commands. You can then perform inserts, updates, and reads across multiple documents, multiple collections, and across globally sharded clusters within the transaction scope knowing that they will be executed in ACID compliance. Visit our documentation pages for language-specific guides to using MongoDB transactions.
Transactions in MongoDB do have a few limitations:
- You can’t read from any of the system collections
- You can’t write to capped collections
- You can’t write to collections that aren’t created already
- You can’t modify or drop collections or indexes
When should I use MongoDB multi-document transactions?
You’ll want to think of multi-document transactions as a powerful tool that’s there when you need it, but no substitute for well-designed document schemas that take good advantage of document-level atomicity. Document stores are powerful because they allow you to structure your data flexibly, and scale-out horizontally with next to no performance penalty. Cases that clearly require instantly consistent transactions, use transactions. Cases that could be eventually consistent can be handled in batch or with Realm Triggers, and cases that could be handled by keeping related data in a single document can be handled the simple way.