Going Deeper: Production MongoDBPro· 35 min read

Multi-Document Transactions

When several writes must all succeed together — or all be undone — a transaction guarantees it. Essential for money, orders and anything that must stay consistent.

What you will learn

  • Explain what ACID and a transaction guarantee
  • Run a transaction with a session: start, commit, abort
  • Know when a transaction is needed and when it is overkill

The all-or-nothing problem

Imagine transferring 500 rupees from Asha to Ravi. That is two writes: subtract 500 from Asha, add 500 to Ravi. Now suppose the server crashes between them — Asha has lost 500 and Ravi never got it. The money has vanished. The fix is a transaction: a group of writes that either all succeed or all get undone, never half-done.

Databases describe this guarantee with the word ACID — four promises a transaction makes:

LetterPromise
A — AtomicityAll writes happen, or none do (no half-finished transfer)
C — ConsistencyThe data obeys its rules before and after
I — IsolationConcurrent transactions do not see each other half-done
D — DurabilityOnce committed, the change survives a crash

Note: A single document update in MongoDB is already atomic — that one write fully happens or fully fails on its own. You only need a transaction when two or more documents must change as a unit.

Running a transaction

A transaction runs inside a session — think of a session as a bracket around your writes. You start the transaction, do your writes through the session, then commit to make them permanent, or abort to undo them all if anything went wrong. Here it is in Mongoose:

A money transfer as one atomic transaction
const session = await mongoose.startSession();
session.startTransaction();
try {
  await Account.updateOne(
    { name: "Asha" }, { $inc: { balance: -500 } }, { session }
  );
  await Account.updateOne(
    { name: "Ravi" }, { $inc: { balance: 500 } }, { session }
  );
  await session.commitTransaction();
} catch (err) {
  await session.abortTransaction();
} finally {
  session.endSession();
}

Walking through it. startSession then startTransaction open the bracket. Both updateOne calls pass { session } so MongoDB knows they belong to the same transaction — the first subtracts 500 from Asha ($inc: { balance: -500 }), the second adds 500 to Ravi. If both succeed, commitTransaction makes them permanent together. If either one throws, the catch runs abortTransaction, which rolls back — undoing even the write that did succeed, so the books stay balanced. finally always closes the session to free resources.

Note: Output (on success): both balances change together — Asha 500 lower, Ravi 500 higher. Output (on failure): abortTransaction undoes everything, so NEITHER balance changes. The money is never lost or duplicated.

The lifecycle of every transaction follows the same five steps:

  1. Start a session with startSession.
  2. Open the transaction with startTransaction.
  3. Do each write, passing the { session } option so they are part of the transaction.
  4. If all writes succeed, commitTransaction saves them together permanently.
  5. If any write throws, abortTransaction rolls them all back; either way, endSession cleans up.

Watch out: Transactions cost extra performance and coordination, so use them only when multiple documents must change together — payments, transfers, placing an order that updates stock. For a single-document change, you do not need one; that write is already atomic.

Tip: Transactions require a replica set (covered in the next lesson). MongoDB Atlas runs your free cluster as a replica set already, so transactions work out of the box there.

Q. In a transaction, what does abortTransaction() do if one of the writes fails?

Answer: Abort rolls back every write in the transaction, guaranteeing all-or-nothing (atomicity). Commit is what makes them permanent together.

✍️ Practice

  1. Write a transaction that moves a value between two documents (e.g. transfer points between two users).
  2. Force the second write to fail and confirm the first write is rolled back.

🏠 Homework

  1. Model “place an order”: in one transaction, create an order document AND decrease the product’s stock count, aborting if stock would go below zero.
Want to learn this with a mentor?

CodingClave runs guided, project-based training (28-day, 45-day & 6-month batches).

Explore Training →