pluginagentmarketplace/custom-plugin-mongodb · Archived

mongodb-transactions

Master MongoDB ACID transactions for multi-document operations. Learn session management, transaction mechanics, error handling, and production patterns. Guarantee data consistency across multiple operations.

First seen Feb 28, 2026

Installation

$ npx skills add pluginagentmarketplace/custom-plugin-mongodb --skill mongodb-transactions

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from pluginagentmarketplace/custom-plugin-mongodb · top by installs.

npx skills add pluginagentmarketplace/custom-plugin-mongodb

Browse all from pluginagentmarketplace/custom-plugin-mongodb

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 1
License LICENSE
Default branch main
Open issues 0
Status Archived

Skill metadata

Parsed from SKILL.md frontmatter.

Version2.1.0

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 10,451 B
  • docs SUMMARY.md 236 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 6 installs

SKILL.md

MongoDB Multi-Document Transactions

Guarantee consistency with ACID transactions across multiple operations.

Quick Start

Basic Transaction

const session = client.startSession()

try {
  await session.withTransaction(async () => {
    // All operations here are atomic
    await users.insertOne({ name: 'John' }, { session })
    await accounts.insertOne({ userId: 'xxx', balance: 100 }, { session })

    // If any fails, ALL roll back
  })
} catch (error) {
  console.error('Transaction failed:', error)
} finally {
  await session.endSession()
}

Real-World: Money Transfer

async function transferMoney(fromId, toId, amount) {
  const session = client.startSession()

  try {
    await session.withTransaction(async () => {
      // Deduct from account A
      await accounts.updateOne(
        { _id: fromId },
        { $inc: { balance: -amount } },
        { session }
      )

      // Add to account B
      await accounts.updateOne(
        { _id: toId },
        { $inc: { balance: amount } },
        { session }
      )

      // Both succeed, or both rollback - NO PARTIAL TRANSFERS!
    })
  } catch (error) {
    // Transaction failed, money not transferred
    console.error('Transfer failed:', error)
  } finally {
    await session.endSession()
  }
}

Transaction Requirements

MongoDB Version

  • MongoDB 4.0+: Single-document transactions (all versions)
  • MongoDB 4.0: Multi-document transactions (replica sets)
  • MongoDB 4.2+: Multi-document transactions (sharded clusters)

Deployment Type

  • Replica Set: Required for transactions
  • Sharded Cluster: MongoDB 4.2+
  • Standalone: Single-document transactions only
  • Atlas Free: No transactions (shared clusters)

Session Management

Create Session

const session = client.startSession()

// Configure session
const session = client.startSession({
  defaultTransactionOptions: {
    readConcern: { level: 'snapshot' },
    writeConcern: { w: 'majority' },
    readPreference: 'primary'
  }
})

Session Lifecycle

// 1. Start session
const session = client.startSession()

// 2. Start transaction
session.startTransaction()

// 3. Execute operations with session
await collection.insertOne(doc, { session })

// 4. Commit or abort
await session.commitTransaction()  // Success
await session.abortTransaction()   // Rollback

// 5. End session
await session.endSession()

Transaction Options

Read Concern

// snapshot: See committed data at transaction start
// local: See latest data (default)
// majority: See data confirmed on majority
// linearizable: Latest confirmed data

await session.withTransaction(async () => {
  // Operations
}, {
  readConcern: { level: 'snapshot' }
})

Write Concern

// w: 1 (default): Acknowledged by primary
// w: 'majority': Acknowledged by majority
// w: N: Acknowledged by N replicas

await session.withTransaction(async () => {
  // Operations
}, {
  writeConcern: { w: 'majority' }
})

Read Preference

// primary: Read from primary only
// primaryPreferred: Primary, fallback to secondary
// secondary: Read from secondary
// secondaryPreferred: Secondary, fallback to primary
// nearest: Nearest server

{
  readPreference: 'primary'
}

Error Handling

Handle Transaction Errors

async function robustTransaction() {
  const session = client.startSession()

  try {
    await session.withTransaction(async () => {
      // Operations
    })
  } catch (error) {
    if (error.hasErrorLabel('TransientTransactionError')) {
      // Temporary error - retry
      return robustTransaction()
    } else if (error.hasErrorLabel('UnknownTransactionCommitResult')) {
      // Commit outcome unknown - check state
      console.log('Commit outcome unknown')
    } else {
      // Fatal error
      throw error
    }
  } finally {
    await session.endSession()
  }
}

Retry Logic

async function executeWithRetry(fn, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    const session = client.startSession()

    try {
      await session.withTransaction(async () => {
        await fn(session)
      })
      return  // Success
    } catch (error) {
      if (error.hasErrorLabel('TransientTransactionError') && attempt < maxRetries) {
        continue  // Retry
      } else {
        throw error
      }
    } finally {
      await session.endSession()
    }
  }
}

Real-World Examples

Order Placement with Inventory

async function placeOrder(userId, items) {
  const session = client.startSession()

  try {
    await session.withTransaction(async () => {
      // 1. Create order
      const order = {
        userId,
        items,
        status: 'pending',
        createdAt: new Date()
      }
      const orderResult = await orders.insertOne(order, { session })

      // 2. Update inventory
      for (const item of items) {
        const updated = await products.findOneAndUpdate(
          { _id: item.productId },
          { $inc: { stock: -item.quantity } },
          { session, returnDocument: 'after' }
        )

        // Check if stock went negative
        if (updated.value.stock < 0) {
          throw new Error('Insufficient inventory')
        }
      }

      // 3. Deduct from user account
      const userUpdate = await users.findOneAndUpdate(
        { _id: userId },
        { $inc: { balance: -calculateTotal(items) } },
        { session, returnDocument: 'after' }
      )

      if (userUpdate.value.balance < 0) {
        throw new Error('Insufficient funds')
      }

      return orderResult.insertedId
    })
  } catch (error) {
    // ALL operations rolled back if any fails
    // Inventory stays same
    // User balance unchanged
    // Order not created
    console.error('Order failed:', error.message)
    throw error
  } finally {
    await session.endSession()
  }
}

Account Reconciliation

async function reconcileAccounts(mainId, secondaryIds) {
  const session = client.startSession()

  try {
    await session.withTransaction(async () => {
      // Calculate total balance
      const secondary = await accounts.find(
        { _id: { $in: secondaryIds } },
        { session }
      ).toArray()
      const totalBalance = secondary.reduce((sum, acc) => sum + acc.balance, 0)

      // Update main account
      await accounts.updateOne(
        { _id: mainId },
        { $set: { balance: totalBalance } },
        { session }
      )

      // Delete secondary accounts
      await accounts.deleteMany(
        { _id: { $in: secondaryIds } },
        { session }
      )

      // Log reconciliation
      await reconciliationLog.insertOne({
        mainId,
        secondaryIds,
        totalBalance,
        timestamp: new Date()
      }, { session })

      // All succeed together, or all rollback
    })
  } finally {
    await session.endSession()
  }
}

Limitations & Considerations

Transaction Limits

- Maximum 16MB of write operations
- Cannot create/drop collections
- Cannot create/drop indexes
- Cannot alter collections
- Cannot write to system collections

Performance Impact

- Transactions have overhead
- Write operations slower (more coordination)
- Locking increases lock contention
- Not for every operation

Best Practices

✅ Transaction Best Practices:

  1. Keep short - Minimize lock time
  2. Retry transient errors - Network issues happen
  3. Order operations - Prevent deadlocks
  4. Use appropriate write concern - 'majority' for safety
  5. Monitor latency - Transactions add overhead

✅ When to Use:

  1. ✅ Money transfers
  2. ✅ Order processing
  3. ✅ Inventory management
  4. ✅ Account operations
  5. ✅ Any multi-collection atomic operations

❌ When NOT to Use:

  1. ❌ Single document operations (inherently atomic)
  2. ❌ Simple inserts/updates
  3. ❌ Performance-critical reads
  4. ❌ Batch operations (use bulk)
  5. ❌ If not on replica set

Next Steps

  1. Learn session basics - StartSession, endSession
  2. Write simple transaction - Insert and update
  3. Add error handling - Try-catch blocks
  4. Implement retry logic - Handle transient errors
  5. Monitor performance - Measure transaction time

Guarantee consistency with transactions! ✅