Transactions
Multi-document transactions with snapshot isolation across ranges.
MongoDB transactions work the same. You open a session, do several operations and commit or abort them together. The operations can touch documents on different ranges and nodes.
Requirements
- A connection with a user that has
readWriteon the databases the transaction touches.
Open a transaction
const session = db.getMongo().startSession();
session.withTransaction(() => {
const accounts = session.getDatabase("bank").accounts;
accounts.updateOne({ _id: "A" }, { $inc: { balance: -100 } });
accounts.updateOne({ _id: "B" }, { $inc: { balance: 100 } });
});Isolation
Each transaction reads a snapshot at its read timestamp and sees its own writes. Inside a transaction, readConcern
local, majority and snapshot all read that same snapshot.
How it commits
If every key of the transaction is in one range, it commits in one phase. If not, each range keeps provisional versions and a transaction record decides; cleaning up those versions continues in the background after the answer.
Limits and errors
The error labels (TransientTransactionError, UnknownTransactionCommitResult) and commit retry are MongoDB's, so the
drivers' withTransaction retries what it should. transactionLifetimeLimitSeconds is 60 by default and changes with
setParameter.
Causal consistency
The drivers' sessions with causalConsistency work: a read with afterClusterTime sees everything the session already wrote or read,
also when it goes to another replica.
Check
After the commit, a read of both accounts sees both changes; if the transaction aborts, it sees neither.
Common problems
- The transaction aborts after 60 seconds, the default of
transactionLifetimeLimitSeconds. Split it or raise the limit withsetParameter. - An operation fails with
TransientTransactionError.withTransactionretries it; if you write the loop yourself, retry the whole transaction.