Transactions
What a transaction is
Multi-document transactions give ACID semantics across documents, collections, databases, and (on sharded clusters, since 4.2) shards. They run inside a session: session.startTransaction({readConcern: {level: "snapshot"}, writeConcern: {w: "majority"}}) then commitTransaction() or abortTransaction(). Generally you should not hand-roll retries around a raw transaction; use the driver's withTransaction helper, which handles the two retry categories for you.
Required settings
Transactions require readConcern: "snapshot" and writeConcern: "majority", and operations must use primary read preference. Supported operations exclude $out/$merge, createIndex, and writes to the admin/config databases; collection creation inside a transaction is restricted.
Limits and failure modes
A transaction defaults to a 60-second lifetime (transactionLifetimeLimitSeconds) and its total oplog footprint must stay under 16 MB. Write conflicts surface as TransientTransactionError - the correct response is to retry the whole transaction body, not just the failing statement. Commit failures return UnknownTransactionCommitResult, which should be retried with a commit, since the commit may already have applied.
Cost
Transactions hold locks and snapshots, so long transactions block other writers and increase cache pressure. Keep them short and touch as few documents as possible.
Worked example (funds transfer)
startTransaction; 2.updateOne({_id: from, balance: {$gte: amount}}, {$inc: {balance: -amount}}); 3. abort ifmatchedCount === 0; 4.updateOne({_id: to}, {$inc: {balance: amount}}); 5.commitTransaction. Wrap steps 1–5 inwithTransactionso transient errors retry the body.