advanced

Transactions

Use multi-document transactions sparingly when invariants cross documents and simpler document modeling is insufficient.

Multi-document ACID transactions let MongoDB coordinate reads and writes across collections when invariants span documents. They are available on replica sets and sharded clusters (with constraints), but should be a last resort after modeling and idempotent workflows.

					const session = client.startSession()
try {
  await session.withTransaction(async () => {
    await accounts.updateOne(
      { _id: fromId, balance: { $gte: amount } },
      { $inc: { balance: -amount } },
      { session }
    )
    await accounts.updateOne(
      { _id: toId },
      { $inc: { balance: amount } },
      { session }
    )
    await ledger.insertOne({ fromId, toId, amount, at: new Date() }, { session })
  })
} finally {
  await session.endSession()
}
				

| Use transactions when | Avoid when | |-----------------------|------------| | Invariant crosses documents and collections | Single-document update suffices | | Modeling cannot embed safely | High throughput hot path | | Compensating logic is riskier than atomicity | Long-running work inside txn | | Retry-safe idempotent design exists | Cross-shard patterns are unsupported |

Transactions add latency, lock contention, and oplog pressure. Default snapshot read concern helps consistent reads within the transaction. Always handle `TransientTransactionError` with bounded retries.

On interviews: say what invariant needs atomicity, why one document was not enough, and how you keep transactions short.

Common pitfalls: long transactions holding locks; transactions as default instead of aggregate design; ignoring shard key placement; missing retry logic; assuming exactly-once without idempotency keys.

The trade-off is cross-document correctness versus throughput — transactions buy atomic invariants at the price of contention and operational sensitivity on hot paths.

Checklist:

  • State the multi-document invariant explicitly.
  • Keep transaction scope minimal and fast.
  • Design idempotent retries with error labels.
  • Prefer single-document atomic updates when possible.