Phase 5: Transactions, Concurrency Control & The Lock Hierarchy¶
Audience: Principal Distributed Systems Architect & High-Throughput Database Engineer
Source References:src/mongo/db/concurrency/,src/mongo/db/storage/wiredtiger/wiredtiger_session_cache.cpp
1. Multi-Document ACID Transactions¶
MongoDB provides full ACID guarantees across multiple documents, collections, and shards:
// Enterprise Multi-Document Transaction Example
const session = client.startSession();
session.startTransaction({
readConcern: { level: "snapshot" },
writeConcern: { w: "majority", j: true }
});
try {
const accounts = session.getDatabase("banking").accounts;
await accounts.updateOne({ _id: "A" }, { $inc: { balance: -500 } }, { session });
await accounts.updateOne({ _id: "B" }, { $inc: { balance: 500 } }, { session });
await session.commitTransaction();
} catch (error) {
await session.abortTransaction();
} finally {
await session.endSession();
}
1.1 The 60-Second Transaction Lifetime Ceiling¶
Transactions are subject to transactionLifetimeLimitSeconds (default: 60 seconds).
- If a transaction stays open longer than 60 seconds, mongod automatically aborts it and releases all locks.
- Why? An open transaction pins a WiredTiger snapshot timestamp. WiredTiger cannot prune its in-memory MVCC update chains past that pinned timestamp, causing the cache to bloat and triggering severe memory pressure.
2. Read Concerns: Consistency & Isolation Spectrum¶
Consistency vs. Latency Spectrum:
[ local ] ──► [ available ] ──► [ majority ] ──► [ snapshot ] ──► [ linearizable ]
(Fastest) (Strictest)
| Read Concern | Guarantees | Mechanism |
|---|---|---|
local |
Returns the node's most recent in-memory data. | Reads without checking replication status. Subject to rollback if primary crashes. |
available |
Identical to local on replica sets; on sharded clusters, does not filter orphan documents during chunk migrations. |
Lowest latency on secondaries. |
majority |
Guarantees the data read will NEVER be rolled back. | Reads from an in-memory WiredTiger snapshot timestamp that is acknowledged by \(\lfloor N/2 \rfloor + 1\) voting members. |
snapshot |
Monotonic point-in-time snapshot isolation across multiple operations and collections. | Used in transactions. Reads state as of transaction start timestamp. |
linearizable |
Real-time serializability. Reads reflect writes acknowledged prior to read invocation. | Primary executes an active round-trip quorum heartbeat with secondaries during query execution to verify it has not been partitioned. |
3. Write Concerns: Durability Spectrum¶
Write Execution Lifecycle:
[Client] ──► [Primary RAM (WiredTiger Cache)] ──► [Primary Journal (NVMe)] ──► [Secondary Replicas]
▲ ▲ ▲
│ │ │
{ w: 1 } { j: true } { w: "majority" }
{ w: 1 }: Client receives acknowledgment the moment data is updated in the primary's memory cache. If the primary loses power before flushing to disk or replicating, data is permanently lost.{ w: "majority" }: Client waits until the write has been replicated and acknowledged in memory by a majority of replica set nodes. Protects against primary hardware death.{ j: true }: Client waits until the primary has committed the transaction to the on-disk Write-Ahead Journal (WiredTigerLog.*).
4. The Hierarchical Lock Manager¶
MongoDB employs a multi-granularity lock manager (src/mongo/db/concurrency/lock_manager.h) to coordinate operations across three tiers: Global, Database, and Collection.
4.1 The Four Lock Modes¶
┌───────┬────────────────────────────────────────────────────────────────────────┐
│ Mode │ Description & Usage │
├───────┼────────────────────────────────────────────────────────────────────────┤
│ IS │ Intent Shared: Indicates intention to read at a lower level. │
│ IX │ Intent Exclusive: Indicates intention to modify at a lower level. │
│ S │ Shared: Read-only access to entire resource (e.g. index build). │
│ X │ Exclusive: Full exclusive write access (e.g. dropCollection). │
└───────┴────────────────────────────────────────────────────────────────────────┘
4.2 Lock Compatibility Matrix¶
Requested Mode ──► IS IX S X
Granted Mode │
IS YES YES YES NO
IX YES YES NO NO
S YES NO YES NO
X NO NO NO NO
4.3 Lock Conversion & Deadlock Detection¶
- When executing a normal insert (
insertOne), MongoDB requests: - Global:
IX - Database:
IX - Collection:
IX - Document: Handled by WiredTiger without locks (via MVCC).
- Multiple threads can hold
IXon the same database and collection simultaneously. - When an administrative operation (e.g.,
db.collection.drop()) arrives, it requests anXlock on the collection. It queues behind activeIXholders, and blocks all subsequent incomingIS/IXqueries until the drop finishes. - MongoDB runs an internal deadlock detection cycle every 500ms, aborting the newest transaction if a cycle is detected.