MongoDB Transactions

What are Transactions?

Transactions in MongoDB are operations that allow you to execute multiple operations as a single unit of work. They ensure that all operations either succeed together or fail together, maintaining data consistency across your database.

MongoDB Transactions

ACID Properties in MongoDB Transactions

ACID Properties

Atomicity

All operations in a transaction are treated as a single unit. Either all operations succeed, or none of them do.

// Example of atomic transaction
const session = client.startSession();
try {
    session.startTransaction();
    
    // Perform multiple operations
    await accounts.updateOne(
        { _id: "account1" },
        { $inc: { balance: -100 } },
        { session }
    );
    await accounts.updateOne(
        { _id: "account2" },
        { $inc: { balance: 100 } },
        { session }
    );
    
    await session.commitTransaction();
} catch (error) {
    await session.abortTransaction();
    throw error;
} finally {
    session.endSession();
}

Consistency

Transactions maintain database consistency by ensuring that all data remains in a valid state.

// Example of maintaining consistency
const session = client.startSession();
try {
    session.startTransaction();
    
    // Check balance before transfer
    const account = await accounts.findOne(
        { _id: "account1" },
        { session }
    );
    
    if (account.balance < 100) {
        throw new Error("Insufficient funds");
    }
    
    // Perform transfer
    await accounts.updateOne(
        { _id: "account1" },
        { $inc: { balance: -100 } },
        { session }
    );
    await accounts.updateOne(
        { _id: "account2" },
        { $inc: { balance: 100 } },
        { session }
    );
    
    await session.commitTransaction();
} catch (error) {
    await session.abortTransaction();
    throw error;
} finally {
    session.endSession();
}

Isolation

Transactions are isolated from each other, preventing concurrent transactions from interfering with each other.

// Example of transaction isolation
const session = client.startSession();
try {
    session.startTransaction();
    
    // Read with transaction isolation
    const result = await orders.findOne(
        { _id: "order1" },
        { session }
    );
    
    // Update with transaction isolation
    await orders.updateOne(
        { _id: "order1" },
        { $set: { status: "processing" } },
        { session }
    );
    
    await session.commitTransaction();
} catch (error) {
    await session.abortTransaction();
    throw error;
} finally {
    session.endSession();
}

Durability

Once a transaction is committed, its changes are permanent and survive system failures.

// Example of durable transaction
const session = client.startSession();
try {
    session.startTransaction();
    
    // Perform critical operations
    await orders.insertOne({
        _id: "order1",
        items: ["item1", "item2"],
        total: 200
    }, { session });
    
    await inventory.updateMany(
        { _id: { $in: ["item1", "item2"] } },
        { $inc: { quantity: -1 } },
        { session }
    );
    
    // Commit ensures durability
    await session.commitTransaction();
} catch (error) {
    await session.abortTransaction();
    throw error;
} finally {
    session.endSession();
}

Transaction Operations

Starting a Transaction

// Start a new session
const session = client.startSession();

// Start a transaction
session.startTransaction();

Committing a Transaction

// Commit the transaction
await session.commitTransaction();

// End the session
session.endSession();

Aborting a Transaction

// Abort the transaction
await session.abortTransaction();

// End the session
session.endSession();

Best Practices

  • Keep transactions as short as possible
  • Use appropriate read and write concerns
  • Handle errors and implement retry logic
  • Monitor transaction performance
  • Consider using transactions only when necessary

Next Steps

Now that you understand transactions, you can explore: