Navigation

Transactions and Operations

For transactions:

  • You can specify read/write (CRUD) operations on existing collections. For a list of CRUD operations, see CRUD Operations.

  • When using feature compatibility version (fcv) "4.4" or greater, 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 cannot write to capped collections. (Starting in MongoDB 4.2)

  • You cannot read/write to collections in the config, admin, or local databases.

  • You cannot write to system.* collections.

  • You cannot return the supported operation’s query plan (i.e. explain).

  • For cursors created outside of a transaction, you cannot call getMore inside the transaction.
  • For cursors created in a transaction, you cannot call getMore outside the transaction.
  • Starting in MongoDB 4.2, you cannot specify killCursors as the first operation in a transaction.

Operations that affect the database catalog, such as creating or dropping a collection or an index, are not allowed in multi-document transactions. For example, a multi-document transaction cannot include an insert operation that would result in the creation of a new collection. See Restricted Operations.

Operations Supported in Multi-Document Transactions

CRUD Operations

The following read/write operations are allowed in transactions:

Method Command Note
db.collection.aggregate() aggregate

Excluding the following stages:

db.collection.countDocuments()  

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.

db.collection.distinct() distinct

Available on unsharded collections.

For sharded collections, use the aggregation pipeline with the $group stage. See Distinct Operation.
db.collection.find() find  
  geoSearch  
delete  
findAndModify

For feature compatibility version (fcv) "4.4" or greater, if the update/replace operation is run with upsert: true against a non-existing collection, the collection is implicitly created.

For fcv "4.2" or less, if upsert: true, the operation must be run against an existing collection.

See also

DDL Operations

insert

For feature compatibility version (fcv) "4.4" or greater, when run against a non-existing collection, the collection is implicitly created.

For fcv "4.2" or less, can only be run against an existing collection.

See also

DDL Operations

db.collection.save()  

For feature compatibility version (fcv) "4.4" or greater, if an insert against a non-existing collection, the collection is implicitly created.

With fcv "4.2" or less, if an insert, can only be run against an existing collection.

See also

DDL Operations

update

For feature compatibility version (fcv) "4.4" or greater, if run with upsert: true against a non-existing collection, the collection is implicitly created.

For fcv "4.2" or less, if upsert: true, the operation must be run against an existing collection.

See also

DDL Operations

 

For feature compatibility version (fcv) "4.4" and greater, if an insert operation or update operation with upsert: true is run in a transaction against a non-existing collection, the collection is implicitly created.

For fcv "4.2" or less, the collection must already exist for insert and upsert: true operations.

See also

DDL Operations

Updates to Shard Key Values

Starting in MongoDB 4.2, 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.

Count Operation

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

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

Starting in MongoDB 4.0.3, the mongo shell provides the db.collection.countDocuments() helper method that uses the $group with a $sum expression to perform a count.

Distinct Operation

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.

DDL Operations

Starting in MongoDB 4.4 with feature compatibility version (fcv) "4.4", you can create collections and indexes inside a multi-document transaction if the transaction is not a cross-shard write transaction.

Explicit DDL Operations

Command Method Notes
create db.createCollection() See also the Implicit DDL Operations.
createIndexes 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.

Implicit DDL Operations

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
insert
db.collection.save() results in an insert  
db.collection.updateOne() with upsert: true
db.collection.updateMany() with upsert: true
db.collection.replaceOne() with upsert: true
db.collection.update() with upsert: true
update with upsert: true
db.collection.bulkWrite() with insert or upsert:true operations
Various Bulk Operation Methods 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 Operations

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

Restricted Operations

Changed in version 4.4.

The following operations are not allowed in transactions: