MongoDB: How COMMIT Works

MongoDB: How COMMIT Works Internally

Table of Contents



1. No COMMIT Needed for Single Writes

In Oracle, nothing is permanent until you type COMMIT. If the session dies before that, everything is rolled back. MongoDB is the opposite: every single-document write is committed the moment it finishes. There is no COMMIT to type and no ROLLBACK to undo it.

MongoDBOracle
db.orders.insertOne(
  { item: "laptop", qty: 1 }
)
// Done. Already permanent.

db.orders.updateOne(
  { item: "laptop" },
  { $set: { qty: 5 } }
)
// Done. Already permanent.
INSERT INTO orders (item, qty)
VALUES ('laptop', 1);

UPDATE orders SET qty = 5
WHERE item = 'laptop';

COMMIT;  -- without this, both
         -- changes are lost

Why no COMMIT? A single document in MongoDB is like a single row in Oracle — changing it is atomic. All fields update together or not at all, even nested arrays and sub-documents. So there is nothing left to “commit.” The best practice is to keep related data inside one document so you rarely need a multi-document transaction.

MongoDB does have a real COMMIT and ROLLBACK, but only for multi-document transactions (Section 4).

2. What Happens Inside When You Write

Even though you don’t type COMMIT, MongoDB still protects your data the same way Oracle does — with a write-ahead log (journal) and periodic checkpoints. Here is the path a single write takes:


+----------------------------------------------+
| 1. CLIENT sends the write                    |
|    db.orders.insertOne({ item: "laptop" })   |
+-----------------------+----------------------+
                        |
                        v
+----------------------------------------------+
| 2. INTENT LOCK on the collection             |
|    (other writers can proceed in parallel)   |
+-----------------------+----------------------+
                        |
                        v
+----------------------------------------------+
| 3. WIREDTIGER CACHE  (like Oracle SGA)       |    w:1 returns OK from here
|    the change is applied in memory           |
+-----------------------+----------------------+
                        |
                        v
+----------------------------------------------+
| 4. JOURNAL  (like Oracle redo log)           |
|    the change is recorded in the journal     |
+-----------------------+----------------------+
                        |
                        v
+----------------------------------------------+
| 5. JOURNAL FLUSH TO DISK  (like LGWR)        |    j:true waits for this step
|    happens every 100 ms automatically        |    THIS is the real durability point
+-----------------------+----------------------+
                        |
                        v
+----------------------------------------------+
| 6. REPLICATION  (replica set only)           |    w:majority waits for this step
|    secondaries copy the oplog entry          |
+-----------------------+----------------------+
                        |
                        v
+----------------------------------------------+
| 7. ACKNOWLEDGMENT sent to client             |
|    (timing depends on your write concern)    |
+-----------------------+----------------------+
                        |
                        v
+----------------------------------------------+
| 8. CHECKPOINT  (like Oracle DBWR)            |
|    every 60 s, dirty pages go to data files  |
+-----------------------+----------------------+

If the server crashes, MongoDB recovers exactly like Oracle: it starts from the last checkpoint and replays the journal forward. The matching terms are:

MongoDBOracle
JournalRedo log
Journal flush (every 100 ms)LGWR flush at COMMIT
WiredTiger cacheBuffer cache (SGA)
Checkpoint (every 60 s)DBWR checkpoint
OplogArchive log / Data Guard redo

3. Write Concern — How Safe Is Your Write?

In Oracle, COMMIT always waits for LGWR to flush the redo to disk. In MongoDB, you get to choose how safe each write must be. This choice is called the write concern.

MongoDBOracle
w: 1 — default on a standalone server.
Returns OK as soon as the primary has the write in memory. The journal flushes within 100 ms on its own. A crash in that tiny window can lose the write.
COMMIT WRITE NOWAIT
Returns before LGWR finishes.
w: 1, j: true
Returns OK only after the journal is flushed to disk. This is the closest match to a normal Oracle COMMIT.
COMMIT (the default)
Waits for LGWR to write the redo to disk.
w: "majority" — default on replica sets from MongoDB 5.0.
Returns OK after most members have the write and flushed it to their journal. Protects against both crashes and failover rollbacks.
Data Guard in Maximum Availability / SYNC mode.
COMMIT waits for the standby to confirm.

// Safest single-node option: wait for journal flush
db.orders.insertOne(
  { item: "laptop", qty: 1 },
  { writeConcern: { w: 1, j: true } }
)

// Safest replica-set option: wait for majority + journal
db.orders.insertOne(
  { item: "phone", qty: 2 },
  { writeConcern: { w: "majority", wtimeout: 5000 } }
)

// Set it once in the connection string
// mongodb://host:27017/?w=majority&journal=true

// Check the cluster-wide default
db.adminCommand({ getDefaultRWConcern: 1 })

4. Transactions — When You Do Need COMMIT and ROLLBACK

Sometimes one document is not enough. If you need to debit one account and credit another, both must succeed or both must fail. For this, MongoDB 4.0+ supports multi-document transactions with a real commitTransaction() and abortTransaction().

MongoDBOracle
const session =
  db.getMongo().startSession()
const accounts =
  session.getDatabase("shop").accounts

session.startTransaction({
  writeConcern: { w: "majority" }
})

try {
  accounts.updateOne(
    { name: "Ravi" },
    { $inc: { balance: -100 } })
  accounts.updateOne(
    { name: "Anu" },
    { $inc: { balance:  100 } })

  session.commitTransaction()
} catch (e) {
  session.abortTransaction()
  throw e
} finally {
  session.endSession()
}
UPDATE accounts
  SET balance = balance - 100
  WHERE name = 'Ravi';

UPDATE accounts
  SET balance = balance + 100
  WHERE name = 'Anu';

COMMIT;

-- or, if something failed:
ROLLBACK;

Here is what happens inside when you call commitTransaction():


+----------------------------------------------+
| 1. startTransaction()                        |
|    opens a private snapshot (read concern)   |
+-----------------------+----------------------+
                        |
                        v
+----------------------------------------------+
| 2. YOUR WRITES run inside the transaction    |
|    other sessions cannot see them yet        |
|    write conflict or 60 s timeout            |
|      --> abortTransaction()  (ROLLBACK)      |
+-----------------------+----------------------+
                        |
                        v
+----------------------------------------------+
| 3. commitTransaction()                       |
|    all changes are saved as one atomic unit  |
+-----------------------+----------------------+
                        |
                        v
+----------------------------------------------+
| 4. JOURNAL FLUSH + WRITE CONCERN             |
|    e.g. w:majority waits for replicas        |
+-----------------------+----------------------+
                        |
                        v
+----------------------------------------------+
| 5. DONE — all changes visible together       |
+-----------------------+----------------------+

The key differences from Oracle:

MongoDBOracle
You must call startTransaction() explicitly.Starts automatically with the first DML.
Requires a replica set or sharded cluster (not standalone).Always available.
Default time limit: 60 seconds (transactionLifetimeLimitSeconds).No default time limit.
If another session touches the same document, your transaction gets a write-conflict error and you retry.The second session waits for the row lock.
No savepoints.SAVEPOINT is supported.
DDL (create/drop collection) is not allowed inside a transaction.DDL issues an implicit COMMIT.

Bottom line for Oracle DBAs: Think of every single MongoDB write as if Oracle automatically ran COMMIT right after the statement. You only need an explicit transaction when multiple documents must change together — all or nothing.

Caution: Your use of any information or materials on this website is entirely at your own risk. It is provided for educational purposes only. It has been tested internally, however, we do not guarantee that it will work for you. Ensure that you run it in your test environment before using.
Thank you
Rajasekhar Amudala