Tutorials Logic, IN info@tutorialslogic.com

MongoDB Transactions ACID Multi Document

ACID Transactions in MongoDB

Use a MongoDB transaction only when one atomic rule spans multiple documents; keep sessions short and make retry behavior explicit.

Since MongoDB 4.0, multi-document ACID transactions are supported on replica sets, and since 4.2 on sharded clusters. Transactions guarantee Atomicity (all or nothing), Consistency (data remains valid), Isolation (concurrent transactions don't interfere), and Durability (committed data persists).

For single-document operations, MongoDB has always been atomic. Multi-document transactions are needed when you need to update multiple documents or collections atomically.

Using Transactions with Sessions

startTransaction, commitTransaction, abortTransaction

startTransaction, commitTransaction, abortTransaction
// Example: Transfer funds between two accounts atomically
const session = db.getMongo().startSession()

session.startTransaction({
  readConcern: { level: "snapshot" },
  writeConcern: { w: "majority" }
})

try {
  const accounts = session.getDatabase("bank").accounts

  // Debit from sender
  accounts.updateOne(
    { accountId: "ACC001", balance: { $gte: 500 } },
    { $inc: { balance: -500 } },
    { session }
  )

  // Credit to receiver
  accounts.updateOne(
    { accountId: "ACC002" },
    { $inc: { balance: 500 } },
    { session }
  )

  // Commit both operations atomically
  session.commitTransaction()
  print("Transaction committed successfully")

} catch (error) {
  // Rollback all changes if anything fails
  session.abortTransaction()
  print("Transaction aborted: " + error.message)

} finally {
  session.endSession()
}

withTransaction() Helper

withTransaction() - Automatic Retry and Cleanup

withTransaction() - Automatic Retry and Cleanup
// withTransaction() handles retries and session cleanup automatically
const session = db.getMongo().startSession()

session.withTransaction(async () => {
  const orders = session.getDatabase("myapp").orders
  const inventory = session.getDatabase("myapp").inventory

  // Create the order
  await orders.insertOne({
    userId: ObjectId("u1"),
    productId: ObjectId("prod1"),
    qty: 2,
    total: 259.98,
    status: "confirmed",
    createdAt: new Date()
  }, { session })

  // Decrement inventory
  await inventory.updateOne(
    { productId: ObjectId("prod1"), stock: { $gte: 2 } },
    { $inc: { stock: -2 } },
    { session }
  )
})

session.endSession()

Transaction Options and Best Practices

Transaction Options and Limitations

Transaction Options and Limitations
// Transaction options
session.startTransaction({
  readConcern:  { level: "snapshot" },  // snapshot, majority, local
  writeConcern: { w: "majority", j: true, wtimeout: 5000 },
  maxCommitTimeMS: 10000   // max time to wait for commit
})

// Read concern levels:
// "local"    - reads most recent data (may not be committed)
// "majority" - reads data confirmed by majority of replica set
// "snapshot" - reads consistent snapshot at transaction start (recommended)

// Write concern:
// w: 1         - acknowledged by primary only
// w: "majority" - acknowledged by majority of replica set (recommended)
// j: true      - write to journal before acknowledging

// Key limitations:
// - Transactions have a 60-second default timeout
// - Maximum 1000 documents modified per transaction (configurable)
// - Cannot create or drop collections inside a transaction
// - Avoid long-running transactions - they hold locks
// - Prefer single-document operations when possible (always atomic)
// - Requires a replica set (even a single-node replica set works)

Using MongoDB transactions only when multiple writes must succeed together

MongoDB transactions allow multiple operations to commit or abort as one unit. They are useful when separate documents must stay consistent, such as transferring money between accounts or updating inventory and order records together. If one operation fails, the transaction can abort so partial changes do not remain.

Transactions are powerful but should not be the first design tool for every write. MongoDB document modeling often avoids transactions by keeping data that changes together inside one document. Use transactions when consistency across multiple documents or collections is genuinely required, and keep them short to reduce locks and retry complexity.

  • Use a session when starting a transaction.
  • Commit only after all required writes succeed.
  • Abort when any required step fails.
  • Design documents to avoid unnecessary multi-document transactions.

Transfer balance with one transaction

Transfer balance with one transaction
const session = client.startSession();
await session.withTransaction(async () => {
  await accounts.updateOne({ _id: from }, { '$inc': { balance: -100 } }, { session });
  await accounts.updateOne({ _id: to }, { '$inc': { balance: 100 } }, { session });
});
Before you move on

MongoDB Transactions ACID Multi Document Mastery Check

5 checks
  • Since MongoDB 4.0, multi-document ACID transactions are supported on replica sets, and since 4.2 on sharded clusters.
  • Transactions guarantee Atomicity (all or nothing), Consistency (data remains valid), Isolation (concurrent transactions don't interfere), and Durability (committed data persists).
  • For single-document operations, MongoDB has always been atomic.
  • Multi-document transactions are needed when you need to update multiple documents or collections atomically.
  • The most common trap here is forgetting which operations must succeed or fail together.

MongoDB Questions Learners Ask

Use one when related changes across documents must commit or roll back together.

No. A write to one document is already atomic.

Transient conflicts or replica-set changes can abort an attempt, so the operation should tolerate retry.

Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.