0
0
MongodbHow-ToBeginner · 4 min read

How to Use Transactions in Mongoose for MongoDB

To use transactions in Mongoose, start a session with startSession(), then execute your operations inside session.withTransaction(). This ensures all operations succeed or fail together, keeping your data consistent.
📐

Syntax

Using transactions in Mongoose involves these steps:

  • Start a session: Call startSession() on your Mongoose connection.
  • Run transaction: Use session.withTransaction() to run your operations atomically.
  • Commit or abort: The transaction commits if all operations succeed, otherwise it aborts.
javascript
const session = await mongoose.startSession();

await session.withTransaction(async () => {
  // Your database operations here
  await Model.create([{ name: 'Example' }], { session });
  // More operations
});

session.endSession();
💻

Example

This example shows how to transfer money between two user accounts atomically using a transaction. Both debit and credit operations succeed or fail together.

javascript
const mongoose = require('mongoose');

async function runTransaction() {
  const session = await mongoose.startSession();
  try {
    await session.withTransaction(async () => {
      const User = mongoose.model('User', new mongoose.Schema({ name: String, balance: Number }));

      const sender = await User.findOne({ name: 'Alice' }).session(session);
      const receiver = await User.findOne({ name: 'Bob' }).session(session);

      if (sender.balance < 100) {
        throw new Error('Insufficient funds');
      }

      sender.balance -= 100;
      receiver.balance += 100;

      await sender.save({ session });
      await receiver.save({ session });
    });
    console.log('Transaction committed successfully');
  } catch (error) {
    console.log('Transaction aborted:', error.message);
  } finally {
    session.endSession();
  }
}

runTransaction();
Output
Transaction committed successfully
⚠️

Common Pitfalls

Common mistakes when using transactions in Mongoose include:

  • Not passing the session option to all operations inside the transaction, causing them to run outside the transaction.
  • Forgetting to endSession(), which can lead to resource leaks.
  • Running transactions on standalone MongoDB servers; transactions require a replica set or sharded cluster.
  • Not handling errors properly inside withTransaction, which can cause unexpected behavior.
javascript
/* Wrong: Missing session option */
await User.create({ name: 'Charlie' }); // This runs outside transaction

/* Right: Pass session to all operations */
await User.create([{ name: 'Charlie' }], { session });
📊

Quick Reference

StepDescription
startSession()Begin a new session for the transaction
withTransaction(fn)Run your operations inside this function atomically
Pass { session }Include session option in all DB operations inside transaction
endSession()Close the session after transaction completes

Key Takeaways

Always start a session with mongoose.startSession() before running a transaction.
Use session.withTransaction() to run multiple operations atomically.
Pass the session option to every database operation inside the transaction.
Transactions require MongoDB replica sets or sharded clusters to work.
Always end the session with session.endSession() to free resources.