For AI agents: a documentation index is available at https://www.mongodb.com/docs/llms.txt — markdown versions of all pages are available by appending .md to any URL path.
Docs Menu

Transactions and Operations

MongoDB provides the ability to use transactions across multiple operations, collections, databases, documents, and shards.

The following read/write operations are allowed in transactions:

Method
Command
Note

Excluding the following query operator expressions:

The method uses the $match aggregation stage for the query and $group aggregation stage with a $sum expression to perform the count.

Available on unsharded collections.

For sharded collections, use the aggregation pipeline with the $group stage. See Distinct Operation.

If the update or replace operation is run with upsert: true on a non-existing collection, the collection is implicitly created.

For more details, see Administration Operations.

If run on a non-existing collection, the collection is implicitly created.

For more details, see Administration Operations.

If run on a non-existing collection, the collection is implicitly created.

For more details, see Administration Operations.

If run on a non-existing collection, the collection is implicitly created.

For more details, see Administration Operations.

Note

Updates to Shard Key Values

You can update a document's shard key value (unless the shard key field is the immutable _id field) by issuing single-document update / findAndModify operations either in a transaction or as a retryable write. For details, see Change a Document's Shard Key Value.

To perform a count operation within a transaction, use the $count aggregation stage or the $group (with a $sum expression) aggregation stage.

MongoDB drivers provide a collection-level API countDocuments(filter, options) as a helper method that uses the $group with a $sum expression to perform a count.

mongosh provides the db.collection.countDocuments() helper method that uses the $group with a $sum expression to perform a count.

To perform a distinct operation within a transaction:

  • For unsharded collections, you can use the db.collection.distinct() method/the distinct command as well as the aggregation pipeline with the $group stage.

  • For sharded collections, you cannot use the db.collection.distinct() method or the distinct command.

    To find the distinct values for a sharded collection, use the aggregation pipeline with the $group stage instead. For example:

    • Instead of db.coll.distinct("x"), use

      db.coll.aggregate([
      { $group: { _id: null, distinctValues: { $addToSet: "$x" } } },
      { $project: { _id: 0 } }
      ])
    • Instead of db.coll.distinct("x", { status: "A" }), use:

      db.coll.aggregate([
      { $match: { status: "A" } },
      { $group: { _id: null, distinctValues: { $addToSet: "$x" } } },
      { $project: { _id: 0 } }
      ])

    The pipeline returns a cursor to a document:

    { "distinctValues" : [ 2, 3, 1 ] }

    Iterate the cursor to access the results document.

You can create collections and indexes in transactions. For details, see Create Collections and Indexes in a Transaction. The collections used in a transaction can be in different databases.

Note

You cannot create new collections in cross-shard write transactions. For example, if you write to an existing collection in one shard and implicitly create a collection in a different shard, MongoDB cannot perform both operations in the same transaction.

You can create collections and indexes inside a distributed transaction if the transaction is not a cross-shard write transaction.

Command
Method
Notes

The index to create must either be on a non-existing collection, in which case, the collection is created as part of the operation, or on a new empty collection created earlier in the same transaction.

Note

For explicit creation of a collection or an index inside a transaction, the transaction read concern level must be "local".

For more information on creating collections and indexes in a transaction, see Create Collections and Indexes in a Transaction.

You can also implicitly create a collection through the following write operations against a non-existing collection:

Method Run against Non-Existing Collection
Command Run against Non-Existing Collection

findAndModify with upsert: true

db.collection.updateOne() with upsert: true
db.collection.updateMany() with upsert: true
db.collection.replaceOne() with upsert: true

update with upsert: true

db.collection.bulkWrite() with insert or upsert:true operations
Various Bulk Operations with insert or upsert:true operations

For other CRUD operations allowed in transactions, see CRUD Operations.

For more information on creating collections and indexes in a transaction, see Create Collections and Indexes in a Transaction.

Informational commands, such as hello, buildInfo, connectionStatus (and their helper methods) are allowed in transactions; however, they cannot be the first operation in the transaction.

The following operations are not allowed in transactions:

  • Creating new collections in cross-shard write transactions. For example, if you write to an existing collection in one shard and implicitly create a collection in a different shard, MongoDB cannot perform both operations in the same transaction.

  • Explicit creation of collections, e.g. db.createCollection() method, and indexes, e.g. db.collection.createIndexes() and db.collection.createIndex() methods, when using a read concern level other than "local".

  • The listCollections and listIndexes commands and their helper methods.

  • Other non-CRUD and non-informational operations, such as createUser, getParameter, count and their helpers.

  • Parallel operations. To update multiple namespaces concurrently, consider using the bulkWrite command instead.

  • Writes to capped collections.

  • Using read concern "snapshot" when reading from a capped collection. (Starting in MongoDB 5.0)

  • Reads/writes to collections in the config, admin, or local databases.

  • Writes to system.* collections.

  • Using explain or similar commands to return the supported operation's query plan.

  • Calling getMore on cursors created outside of a transaction, or calling getMore outside of a transaction on cursors created within a transaction.

  • Specifying the killCursors command as the first operation in a transaction.

    Note

    If you run the killCursors command within a transaction, the server immediately stops the specified cursors. It does not wait for the transaction to commit.