How MongoDB multi-document transactions work
ACID transactions, startSession, withTransaction, commitTransaction, abortTransaction, transaction limitations, performance cost, when to use vs when to avoid
When you need transactions
MongoDB supports multi-document ACID transactions since v4.0 on replica sets and v4.2 on sharded clusters. Use transactions when two or more write operations across one or more collections must succeed or fail atomically โ payment transfers, inventory deductions paired with order creation, or any operation where partial success would leave data in an inconsistent state.
const { MongoClient } = require('mongodb')
const client = new MongoClient(process.env.MONGO_URI)
await client.connect()
const session = client.startSession()
try {
await session.withTransaction(async () => {
const accounts = client.db('bank').collection('accounts')
// Both updateOne calls are atomic โ commit or rollback together
await accounts.updateOne(
{ _id: 'alice', balance: { $gte: 100 } },
{ $inc: { balance: -100 } },
{ session } // always pass the session to every operation
)
await accounts.updateOne(
{ _id: 'bob' },
{ $inc: { balance: 100 } },
{ session }
)
})
console.log('Transfer complete')
} catch (err) {
console.error('Transaction aborted:', err.message)
} finally {
await session.endSession()
await client.close()
}When not to use transactions
Transactions hold locks and add measurable latency overhead. Avoid them for single-document writes โ MongoDB's document model lets you embed related data so many SQL-style multi-table transactions become unnecessary. Never use them for high-throughput event logging or analytics inserts where eventual consistency is perfectly acceptable.
