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 readWrite on the databases the transaction touches.

Open a transaction

JavaScript
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 with setParameter.
  • An operation fails with TransientTransactionError. withTransaction retries it; if you write the loop yourself, retry the whole transaction.

See also