MongoDB transactions.
Basics
with client.start_session() as s:
with s.start_transaction():
db.accounts.update_one({"_id": a}, {"$inc": {"bal": -100}}, session=s)
db.accounts.update_one({"_id": b}, {"$inc": {"bal": 100}}, session=s)
Requires replica set or sharded cluster.
with_transaction (auto-retry)
def txn(session):
db.accounts.update_one({"_id": a}, {"$inc": {"bal": -100}}, session=session)
db.accounts.update_one({"_id": b}, {"$inc": {"bal": 100}}, session=session)
with client.start_session() as s:
s.with_transaction(txn)
Retries on transient errors.
Node
const session = client.startSession();
try {
await session.withTransaction(async () => {
await accounts.updateOne({ _id: a }, { $inc: { bal: -100 } }, { session });
await accounts.updateOne({ _id: b }, { $inc: { bal: 100 } }, { session });
});
} finally {
await session.endSession();
}
Limits
- 1MB oplog entry per op (60s txn limit by default).
- No CRUD on system collections.
- Some ops restricted.
Performance cost
Transactions slower than single-doc updates. Use only when truly needed.
Alternative: schema design
Often you can put related data in single doc + atomic updates:
db.orders.findOneAndUpdate(
{ _id: orderId, "items.id": itemId },
{ $inc: { "items.$.qty": 1, total: 10 } }
)
Single-doc atomic. No transaction needed.
Read concern
s.start_transaction(read_concern=ReadConcern("snapshot"))
snapshot is default for txns. Consistent point-in-time read.
Write concern
s.start_transaction(write_concern=WriteConcern("majority"))
majority for durability.
Error handling
from pymongo.errors import OperationFailure
try:
s.with_transaction(txn)
except OperationFailure as e:
if e.has_error_label("UnknownTransactionCommitResult"):
# ambiguous; idempotent retry safe
pass
Two-phase commit (manual)
For cross-database / cross-cluster: use two-phase commit pattern manually. Mongo’s transactions cover one cluster.
Common mistakes
- Long-running txns (>60s default) → abort.
- Txns to avoid schema design issue (denormalize instead).
- Forgetting
session=param on each op. - Txns in non-replica-set Mongo.
- Heavy writes in txn → contention.
Read this next
If you want my txn patterns, they’re at rajpoot.dev .
Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .