Hướng dẫn share máy in Informational, Transactional

In MongoDB, an operation on a single document is atomic. Because you can use embedded documents and arrays to capture relationships between data in a single document structure instead of normalizing across multiple documents and collections, this single-document atomicity obviates the need for distributed transactions for many practical use cases.

For situations that require atomicity of reads and writes to multiple documents (in a single or multiple collections), MongoDB supports distributed transactions. With distributed transactions, transactions can be used across multiple operations, collections, databases, documents, and shards.


➤ Use the Select your language drop-down menu in the upper-right to set the language of the following example.


Tip

See also:

For situations that require atomicity of reads and writes to multiple documents (in a single or multiple collections), MongoDB supports distributed transactions, including transactions on replica sets and sharded clusters.

Distributed transactions are atomic. They provide an "all-or-nothing" proposition:

  • When a transaction commits, all data changes made in the transaction are saved and visible outside the transaction. That is, a transaction will not commit some of its changes while rolling back others. Until a transaction commits, the data changes made in the transaction are not visible outside the transaction. However, when a transaction writes to multiple shards, not all outside read operations need to wait for the result of the committed transaction to be visible across the shards. For example, if a transaction is committed and write 1 is visible on shard A but write 2 is not yet visible on shard B, an outside read at read concern can read the results of write 1 without seeing write 2.
  • When a transaction aborts, all data changes made in the transaction are discarded without ever becoming visible. For example, if any operation in the transaction fails, the transaction aborts and all data changes made in the transaction are discarded without ever becoming visible.

Important

In most cases, a distributed transaction incurs a greater performance cost over single document writes, and the availability of distributed transactions should not be a replacement for effective schema design. For many scenarios, the will continue to be optimal for your data and use cases. That is, for many scenarios, modeling your data appropriately will minimize the need for distributed transactions.

For additional transactions usage considerations (such as runtime limit and oplog size limit), see also

Tip

See also:

Distributed transactions can be used across multiple operations, collections, databases, documents, and shards.

For transactions:

  • You can create collections and indexes in transactions. For details, see
  • 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 collections.
  • You cannot use read concern when reading from a collection. (Starting in MongoDB 5.0)
  • 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 using

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

    0 or similar commands.
  • For cursors created outside of a transaction, you cannot call inside the transaction.
  • For cursors created in a transaction, you cannot call outside the transaction.
  • You cannot specify as the first operation in a

For a list of operations not supported in transactions, see

Tip

When creating or dropping a collection immediately before starting a transaction, if the collection is accessed within the transaction, issue the create or drop operation with write concern to ensure that the transaction can acquire the required locks.

Tip

See also:

You can perform the following operations inside of a as long as the transaction is not a cross-shard write transaction:

  • Create collections.
  • Create indexes on new empty collections created earlier in the same transaction.

When creating a collection inside a transaction:

  • You can , such as with:
    • an against a non-existing collection, or
    • an with

      db.coll.aggregate([

        { $match: { status: "A" } },  
        { $group: { _id: null, distinctValues: { $addToSet: "$x" } } },  
        { $project: { _id: 0 } }  
      
      ])

      5 against a non-existing collection.
  • You can using the command or its helper

When , the index to create must be on either:

  • a non-existing collection. The collection is created as part of the operation.
  • a new empty collection created earlier in the same transaction.
  • 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 use the

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

    8 stage within a transaction while targeting a sharded collection.
  • For explicit creation of a collection or an index inside a transaction, the transaction read concern level must be . Explicit creation is through:

Tip

See also:

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

MongoDB drivers provide a collection-level API


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

3 as a helper method that uses the with a expression to perform a count. The


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

6 API is deprecated.

provides the helper method that uses the with a expression to perform a count.

To perform a distinct operation within a transaction:

  • For unsharded collections, you can use the method/the command as well as the aggregation pipeline with the stage.
  • For sharded collections, you cannot use the method or the command.

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

    • Instead of

      db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )

      7, use

      db.coll.aggregate([

        { $group: { _id: null, distinctValues: { $addToSet: "$x" } } },  
        { $project: { _id: 0 } }  
      
      ])

    • Instead of

      db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )

      8, 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.

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

Changed in version 4.4.

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.
  • , e.g. method, and indexes, e.g. and methods, when using a read concern level other than
  • The and commands and their helper methods.
  • Other non-CRUD and non-informational operations, such as , , , etc. and their helpers.

Tip

  • Transactions are associated with a session
  • At any given time, you can have at most one open transaction for a session.
  • When using the drivers, each operation in the transaction must be associated with the session. Refer to your driver specific documentation for details.
  • If a session ends and it has an open transaction, the transaction aborts.

Operations in a transaction use the transaction-level

Using the drivers, you can set the transaction-level at the transaction start:

  • If the transaction-level read preference is unset, the transaction uses the session-level read preference.
  • If transaction-level and the session-level read preference are unset, the transaction uses the client-level read preference. By default, the client-level read preference is

that contain read operations must use read preference . All operations in a given transaction must route to the same member.

Operations in a transaction use the transaction-level read concern. That is, any read concern set at the collection and database level is ignored inside the transaction.

You can set the transaction-level read concern at the transaction start.

  • If the transaction-level read concern is unset, the transaction-level read concern defaults to the session-level read concern.
  • If transaction-level and the session-level read concern are unset, the transaction-level read concern defaults to the client-level read concern. By default, client-level read concern is for reads against the primary. See also:
    • Default MongoDB Read Concerns/Write Concerns

Transactions support the following read concern levels:

  • Read concern returns the most recent data available from the node but can be rolled back.
  • For transactions on sharded cluster, read concern cannot guarantee that the data is from the same snapshot view across the shards. If snapshot isolation is required, use read concern.
  • You can inside a transaction. If creating a collection or an index, the transaction must use read concern . If you create a collection, you can use any of the read concerns available for transactions.
  • If the transaction commits with , read concern returns data that has been acknowledged by a majority of the replica set members and can't be rolled back. Otherwise, read concern provides no guarantees that read operations read majority-committed data.
  • For transactions on sharded cluster, read concern can't guarantee that the data is from the same snapshot view across the shards. If snapshot isolation is required, use read concern
  • Read concern returns data from a snapshot of majority committed data if the transaction commits with
  • If the transaction does not use for the commit, the read concern provides no guarantee that read operations used a snapshot of majority-committed data.
  • For transactions on sharded clusters, the view of the data is synchronized across shards.

Transactions use the transaction-level write concern to commit the write operations. Write operations inside transactions must be issued without explicit write concern specification and use the default write concern. At commit time, the writes are then commited using the transaction-level write concern.

Tip

Do not explicitly set the write concern for the individual write operations inside a transaction. Setting write concerns for the individual write operations inside a transaction results in an error.

You can set the transaction-level write concern at the transaction start:

  • If the transaction-level write concern is unset, the transaction-level write concern defaults to the session-level write concern for the commit.
  • If the transaction-level write concern and the session-level write concern are unset, the transaction-level write concern defaults to the client-level write concern of:
    • in MongoDB 5.0 and later, with differences for deployments containing . See

Tip

See also:

Transactions support all write concern values, including:

  • Write concern returns acknowledgement after the commit has been applied to the primary.

    ImportantWhen you commit with write concern, transaction-level read concern provides no guarantees that read operations in the transaction read majority-committed data.When you commit with write concern, transaction-level read concern provides no guarantee that read operations in the transaction used a snapshot of majority-committed data.Write concern returns acknowledgement after the commit has been applied to a majority (M) of voting members, meaning the commit has been applied to the primary and (M-1) voting secondaries.When you commit with write concern, transaction-level read concern guarantees that operations have read majority-committed data. For transactions on sharded clusters, this view of the majority-committed data is not synchronized across shards.When you commit with write concern, transaction-level read concern guarantees that operations have read from a synchronized snapshot of majority-committed data.

    Note

    For various production considerations with using transactions, see . In addition, for sharded clusters, see also

    Transactions whose write operations span multiple shards will error and abort if any transaction operation reads from or writes to a shard that contains an arbiter.

    You cannot run transactions on a sharded cluster that has a shard with set to`admin`8, such as a shard with a voting member that uses the in-memory storage engine.