Skip to content

Node.js + MongoDB

Transactions, Timeouts and Repositories

withSession, maxTimeMS, and keeping MongoDB behind a small data layer.

AdvancedAbout 6 minutes

Module 12 showed startTransaction. In Node, prefer `session.withTransaction(async () => { ... })`: it retries transient errors (failover). Still pass { session } into every operation. Still abort on sold-out — that is not transient. Keep the callback short: no HTTP to Stripe inside the txn.

await client.withSession(async (session) => {
  await session.withTransaction(async () => {
    await orders.insertOne(doc, { session });
    const r = await products.updateOne(
      { name: "Mechanical Keyboard", stock: { $gte: 1 } },
      { $inc: { stock: -1 } },
      { session, maxTimeMS: 2_000 }
    );
    if (r.matchedCount === 0) throw new Error("sold out");
  });
});
withTransaction + per-operation maxTimeMS
TimeoutWhat it bounds
maxTimeMSThis operation on the server
serverSelectionTimeoutMSFinding a usable server (client option)
socketTimeoutMSIdle socket — rarely what you mean
Transaction lifetime~60s default for the whole txn

A repository is a module that receives Db or collections, not req. Routes call placeOrder({ userId, sku }). Tests pass a db. You can read maxTimeMS in one place. You cannot hide a per-request MongoClient behind a repository and call it architecture. Mongoose is another wrapper — next module — not a requirement for this layer.

Interview question

How do you run transactions and timeouts in the Node.js driver?

Think about it first.