100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
MongoDB

Transactions in MongoDB

How multi-document ACID transactions work in MongoDB, when to use them, and their performance tradeoffs compared to single-document atomicity.

Scaling & PracticeIntermediate8 min readJul 10, 2026
Analogies

Why MongoDB Added Multi-Document Transactions

Every single-document write in MongoDB has always been atomic, but many real-world operations touch multiple documents or collections that must succeed or fail together, such as transferring funds between two account documents or updating an order and decrementing inventory. MongoDB 4.0 introduced multi-document ACID transactions for replica sets, and 4.2 extended them to sharded clusters, letting you wrap a sequence of reads and writes so that either all of them commit or none do.

🏏

Cricket analogy: Like a run-out review where both the batsman's dismissal and the fielding side's catch must be confirmed together or the whole review is voided, a transaction ensures a fund transfer's debit and credit both commit or neither does.

Using Transactions with Sessions

Transactions in MongoDB run within a client session, and the driver exposes a withTransaction() helper that automatically retries the transaction on certain transient errors like TransientTransactionError or write conflicts, which is the recommended approach over manually calling startTransaction, commitTransaction, and abortTransaction. Because a transaction holds locks and consumes resources on every shard it touches, keeping the operations inside it minimal and fast is essential to avoid contention with other concurrent writes.

🏏

Cricket analogy: Like a DRS review having an automatic retry protocol if the first replay angle is inconclusive, withTransaction automatically retries a transaction if it hits a transient conflict, rather than making the developer handle it manually.

javascript
const session = client.startSession();

try {
  await session.withTransaction(async () => {
    const accounts = client.db("bank").collection("accounts");

    await accounts.updateOne(
      { _id: "acct-A" },
      { $inc: { balance: -100 } },
      { session }
    );

    await accounts.updateOne(
      { _id: "acct-B" },
      { $inc: { balance: 100 } },
      { session }
    );
  }, {
    readConcern: { level: "snapshot" },
    writeConcern: { w: "majority" }
  });
} finally {
  await session.endSession();
}

Not every atomicity need requires a transaction. A single updateOne() with operators like $set, $inc, and array update operators is already atomic on one document, and schema designs that embed related data into one document often avoid the need for a transaction entirely.

Transaction Limits and Performance Considerations

By default, MongoDB aborts a transaction that runs longer than 60 seconds (transactionLifetimeLimitSeconds) to release locks and prevent it from blocking other operations, and transactions also hold WiredTiger snapshot resources that can grow cache pressure if too many run concurrently. As a result, transactions work best for short, targeted operations touching a handful of documents; bulk operations spanning thousands of documents should generally be redesigned as smaller batches or restructured to avoid needing a transaction at all.

🏏

Cricket analogy: Like a rain-delay rule that abandons a match if play can't resume within a set window to protect the tournament schedule, MongoDB aborts transactions running longer than 60 seconds to protect cluster resources.

Running many long or large transactions concurrently increases WiredTiger cache pressure because each transaction holds a snapshot of the data. In write-heavy clusters this can cause cache eviction stalls that slow down unrelated operations, so batch large bulk changes outside of transactions where full atomicity across the whole batch isn't strictly required.

Read Concern and Isolation

Transactions use snapshot read concern by default, meaning all reads within the transaction see a consistent snapshot of data as of the transaction's start, isolated from concurrent writes happening outside it, and a commit with write concern majority ensures the change is durable before the application considers it complete. Combining readConcern 'snapshot' with writeConcern 'majority' gives you MongoDB's strongest consistency guarantee, sometimes called 'read your own writes' plus cross-shard atomicity for sharded transactions.

🏏

Cricket analogy: Like a scorecard frozen at the moment a review starts so later events don't change what the umpires are judging, snapshot read concern gives a transaction a consistent view unaffected by concurrent writes.

  • Single-document writes are always atomic; multi-document transactions were added in MongoDB 4.0 (replica sets) and 4.2 (sharded clusters).
  • withTransaction() is the recommended API since it automatically retries on transient errors.
  • Transactions default to a 60-second lifetime limit and abort past it to release resources.
  • Keep transactions short and targeted; redesign bulk operations to avoid huge transactions.
  • Snapshot read concern gives a transaction a consistent, isolated view of the data as of its start.
  • Combining snapshot read concern with majority write concern gives MongoDB's strongest consistency guarantee.
  • Consider embedding related data in one document first, since single-document atomicity often avoids needing a transaction.

Practice what you learned

Was this page helpful?

Topics covered

#MongoDB#MongoDBStudyNotes#Database#TransactionsInMongoDB#Transactions#Added#Multi#Document#StudyNotes#SkillVeris