On this page本页内容
In MongoDB, an operation on a single document is atomic. 在MongoDB中,对单个文档的操作是原子的。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 multi-document 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 multi-document transactions. 对于需要对多个文档(在单个或多个集合中)进行原子性读写的情况,MongoDB支持多文档事务。With distributed transactions, transactions can be used across multiple operations, collections, databases, documents, and shards.通过分布式事务,可以跨多个操作、集合、数据库、文档和碎片使用事务。
The following example highlights the key components of the transactions API:以下示例重点介绍了transactions API的关键组件:
The example uses the new callback API for working with transactions, which starts a transaction, executes the specified operations, and commits (or aborts on error). 该示例使用新的回调API处理事务,它启动事务,执行指定的操作,并提交(或在出错时中止)。The new callback API also incorporates retry logic for 新的回调API还包含TransientTransactionError
or UnknownTransactionCommitResult
commit errors.TransientTransactionError
或UnknownTransactionCommitResult
提交错误的重试逻辑。
Important重要的
insert
or update operations with upsert: true
) must be on existing collections if run inside transactions.upsert:true
的插入或更新操作)必须在现有集合上。The example uses the new callback API for working with transactions, which starts a transaction, executes the specified operations, and commits (or aborts on error). The new callback API also incorporates retry logic for TransientTransactionError
or UnknownTransactionCommitResult
commit errors.
Important
insert
or update operations with upsert: true
)
must be on existing collections if run inside transactions.The example uses the new callback API for working with transactions, which starts a transaction, executes the specified operations, and commits (or aborts on error). The new callback API also incorporates retry logic for TransientTransactionError
or UnknownTransactionCommitResult
commit errors.
Important
insert
or update operations with upsert: true
)
must be on existing collections if run inside transactions.The example uses the new callback API for working with transactions, which starts a transaction, executes the specified operations, and commits (or aborts on error). The new callback API also incorporates retry logic for TransientTransactionError
or UnknownTransactionCommitResult
commit errors.
Important
insert
or update operations with upsert: true
)
must be on existing collections if run inside transactions.The example uses the new callback API for working with transactions, which starts a transaction, executes the specified operations, and commits (or aborts on error). The new callback API incorporates retry logic for "TransientTransactionError" or "UnknownTransactionCommitResult" commit errors.
Important
insert
or update operations with upsert: true
)
must be on existing collections if run inside transactions.The example uses the new callback API for working with transactions, which starts a transaction, executes the specified operations, and commits (or aborts on error). The new callback API also incorporates retry logic for TransientTransactionError
or UnknownTransactionCommitResult
commit errors.
Important
insert
or update operations with upsert: true
)
must be on existing collections if run inside transactions.The example uses the new callback API for working with transactions, which starts a transaction, executes the specified operations, and commits (or aborts on error). The new callback API also incorporates retry logic for TransientTransactionError
or UnknownTransactionCommitResult
commit errors.
Important
insert
or update operations with upsert: true
)
must be on existing collections if run inside transactions.The example uses the new callback API for working with transactions, which starts a transaction, executes the specified operations, and commits (or aborts on error). The new callback API also incorporates retry logic for TransientTransactionError
or UnknownTransactionCommitResult
commit errors.
Important
insert
or update operations with upsert: true
)
must be on existing collections if run inside transactions.This example uses the core API. Because the core API does not incorporate retry logic for "TransientTransactionError" or "UnknownTransactionCommitResult" commit errors, the example includes explicit logic to retry the transaction for these errors:
Important
insert
or update operations with upsert: true
)
must be on existing collections if run inside transactions.The example uses the new callback API for working with transactions, which starts a transaction, executes the specified operations, and commits (or aborts on error). The new callback API incorporates retry logic for "TransientTransactionError" or "UnknownTransactionCommitResult" commit errors.
Important
insert
or update operations with upsert: true
)
must be on existing collections if run inside transactions.This example uses the core API. Because the core API does not incorporate retry logic for "TransientTransactionError" or "UnknownTransactionCommitResult" commit errors, the example includes explicit logic to retry the transaction for these errors:
Important
insert
or update operations with upsert: true
)
must be on existing collections if run inside transactions.The example uses the new callback API for working with transactions, which starts a transaction, executes the specified operations, and commits (or aborts on error). The new callback API incorporates retry logic for "TransientTransactionError" or "UnknownTransactionCommitResult" commit errors.
Important
insert
or update operations with upsert: true
)
must be on existing collections if run inside transactions.See also参阅
For an example in 有关mongo
shell, see mongo Shell Example.mongo
shell中的示例,请参阅mongo
shell示例。
Distributed Transactions and Multi-Document Transactions分布式事务和多文档事务
Starting in MongoDB 4.2, the two terms are synonymous. 从MongoDB 4.2开始,这两个术语是同义词。Distributed transactions refer to multi-document transactions on sharded clusters and replica sets. 分布式事务是指分片集群和副本集上的多文档事务。Multi-document transactions (whether on sharded clusters or replica sets) are also known as distributed transactions starting in MongoDB 4.2.从MongoDB 4.2开始,多文档事务(无论是在分片集群还是副本集上)也称为分布式事务。
For situations that require atomicity of reads and writes to multiple documents (in a single or multiple collections), MongoDB supports multi-document transactions:对于需要对多个文档(在单个或多个集合中)进行原子性读写的情况,MongoDB支持多文档事务:
To use transactions on MongoDB 4.2 deployments(replica sets and sharded clusters), clients must use MongoDB drivers updated for MongoDB 4.2.要在MongoDB 4.2部署(副本集和分片集群)上使用事务,客户端必须使用为MongoDB 4.2更新的MongoDB驱动程序。
Multi-document transactions are atomic (i.e. provide an “all-or-nothing” proposition):多文档事务是原子的(即提供“全部或无”命题):
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 例如,如果事务已提交,且写入1在碎片a上可见,但写入2在碎片B上尚不可见,则外部读取-读取关注点"local"
can read the results of write 1 without seeing write 2."local"
可以读取写入1的结果,而不查看写入2。
Important
In most cases, multi-document transaction incurs a greater performance cost over single document writes, and the availability of multi-document transactions should not be a replacement for effective schema design. 在大多数情况下,与单文档写入相比,多文档事务会带来更大的性能成本,而多文档事务的可用性不应取代有效的模式设计。For many scenarios, the denormalized data model (embedded documents and arrays) 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 multi-document transactions.也就是说,对于许多场景,适当地建模数据将最大限度地减少对多文档事务的需求。
For additional transactions usage considerations (such as runtime limit and oplog size limit), see also Production Considerations.有关其他事务使用注意事项(如运行时限制和oplog大小限制),请参阅生产注意事项。
See also参阅
Distributed transactions can be used across multiple operations, collections, databases, documents, and, starting in MongoDB 4.2, shards.分布式事务可以跨多个操作、集合、数据库、文档以及从MongoDB 4.2开始的碎片使用。
For transactions:对于事务:
"4.4"
or greater, you can create collections and indexes in transactions. "4.4"
或更高版本时,可以在事务中创建集合和索引。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.例如,如果在一个碎片中写入现有集合,并在另一个碎片中隐式创建集合,MongoDB无法在同一事务中执行这两个操作。
config
, admin
, or local
databases.config
、admin
或local
数据库中的集合。system.*
collections.system.*
集合。explain
).explain
)。getMore
inside the transaction.getMore
。getMore
outside the transaction.killCursors
as the first operation in a transaction.killCursors
指定为事务中的第一个操作。For a list of operations not supported in transactions, see Restricted Operations.有关事务中不支持的操作的列表,请参阅受限操作。
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 在启动事务之前立即创建或删除集合时,如果在事务中访问了集合,请使用写关注点"majority"
to ensure that the transaction can acquire the required locks."majority"
发出创建或删除操作,以确保事务可以获得所需的锁。
See also参阅
Starting in MongoDB 4.4 with feature compatibility version (fcv) 从功能兼容版本(fcv)"4.4"
, you can create collections and indexes inside a multi-document transaction unless the transaction is a cross-shard write transaction. "4.4"
的MongoDB 4.4开始,您可以在多文档事务中创建集合和索引,除非该事务是跨切分写入事务。With 对于"4.2"
or less, operations that affect the database catalog, such as creating or dropping a collection or an index, are disallowed in transactions."4.2"
或更低版本,事务中不允许执行影响数据库目录的操作,例如创建或删除集合或索引。
When creating a collection inside a transaction:在事务内创建集合时:
upsert: true
against a non-existing collection.upsert:true
的update
/findAndModify
操作。create
command or its helper db.createCollection()
.create
命令或其助手dbcreateCollection()
显式创建集合。When creating an index inside a transaction [1], the index to create must be on either:在事务内创建索引[1]时,要创建的索引必须位于以下任一位置:
[1] | db.collection.createIndex() and db.collection.createIndexes() on existing indexes to check for existence. db.collection.createIndex() 和db.collection.createIndexes() ,以检查是否存在。 |
"local"
. "local"
。create |
db.createCollection() |
createIndexes |
shouldMultiDocTxnCreateCollectionAndIndexes
must be true
(the default). shouldMultiDocTxnCreateCollectionAndIndexes
必须为true
(默认值)。See also参阅
To perform a count operation within a transaction, use the 要在事务中执行计数操作,请使用$count
aggregation stage or the $group
(with a $sum
expression) aggregation stage.$count
聚合阶段或$group
(带有$sum
表达式)聚合阶段。
MongoDB drivers compatible with the 4.0 features provide a collection-level API 与4.0功能兼容的MongoDB驱动程序提供了一个集合级API countDocuments(filter, options)
as a helper method that uses the $group
with a $sum
expression to perform a count. countDocuments(filter, options)
,作为一个助手方法,使用$group
和$sum
表达式来执行计数。The 4.0 drivers have deprecated the 4.0驱动程序不推荐使用count()
API.count()
API。
Starting in MongoDB 4.0.3, the 从MongoDB 4.0.3开始,mongo
shell provides the db.collection.countDocuments()
helper method that uses the $group
with a $sum
expression to perform a count.mongo
shell提供了db.collection.countDocuments()
辅助方法,该方法使用带有$sum
表达式的$group
来执行计数。
To perform a distinct operation within a transaction:要在事务中执行不同的操作:
db.collection.distinct()
method/the distinct
command as well as the aggregation pipeline with the $group
stage.db.collection.distinct()
方法/distinct
命令以及$group
阶段的聚合管道。db.collection.distinct()
method or the distinct
command.db.collection.distinct()
方法或distinct
命令。
To find the distinct values for a sharded collection, use the aggregation pipeline with the 要查找分片集合的不同值,请将聚合管道与$group
stage instead. $group
阶段一起使用。For example:例如:
db.coll.distinct("x")
, usedb.coll.distinct("x")
,而是使用
db.coll.distinct("x", { status: "A" })
, use:db.coll.distinct("x", { status: "A" })
,而是使用:
The pipeline returns a cursor to a document:管道将游标返回到文档:
Iterate the cursor to access the results document.迭代游标以访问结果文档。
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.isMaster
、buildInfo
、connectionStatus
(及其助手方法);但是,它们不能是事务中的第一个操作。
Changed in version 4.4.在版本4.4中更改。
The following operations are not allowed in transactions:事务中不允许进行以下操作:
"4.2"
or lower. "4.2"
或更低版本时创建或删除集合或索引。"4.4"
or greater, you can create collections and indexes in transactions unless the transaction is a cross-shard write transaction. "4.4"
或更高版本,可以在事务中创建集合和索引,除非该事务是跨分片写入事务。db.createCollection()
method, and indexes, e.g. db.collection.createIndexes()
and db.collection.createIndex()
methods, when using a read concern level other than "local"
."local"
的读取关注级别时,显式创建集合(例如db.createCollection()
方法)和索引(例如db.collection.createIndexes()
方法和db.collection.createIndex()
方法)。listCollections
and listIndexes
commands and their helper methods.listCollections
和listIndexes
命令及其助手方法。createUser
, getParameter
, count
, etc. and their helpers.createUser
、getParameter
、count
等及其助手。Operations in a transaction use the transaction-level read preference.事务中的操作使用事务级别的读取首选项。
Using the drivers, you can set the transaction-level read preference at the transaction start:使用驱动程序,可以在事务开始时设置事务级别的读取首选项:
primary
.primary
。Multi-document transactions that contain read operations must use read preference 包含读取操作的多文档事务必须使用读取首选项primary
. primary
。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.您可以在事务开始时设置事务级别的读取关注点。
"local"
for reads against the primary. "local"
的。Transactions support the following read concern levels:事务支持以下读取关注级别:
"local"
¶"local"
returns the most recent data available from the node but can be rolled back."local"
返回节点上可用的最新数据,但可以回滚。"local"
read concern cannot guarantee that the data is from the same snapshot view across the shards. "local"
读关注点不能保证数据来自分片上的同一快照视图。"4.4"
or greater, you can create collections and indexes inside a transaction. "4.4"
或更高版本,您可以在事务中创建集合和索引。"local"
. "local"
读关注点。"majority"
¶"majority"
returns data that has been acknowledged by a majority of the replica set members (i.e. data cannot be rolled back) if the transaction commits with write concern “majority”."majority"
提交,则读关注"majority"
返回大多数副本集成员已确认的数据(即数据无法回滚)。"majority"
read concern provides no guarantees that read operations read majority-committed data."majority"
用于提交,"majority"
读关注点不保证读操作读取多数提交的数据。"majority"
read concern cannot guarantee that the data is from the same snapshot view across the shards. "majority"
读关注点不能保证数据来自分片上的相同快照视图。"snapshot"
读关注点。"snapshot"
¶"snapshot"
returns data from a snapshot of majority committed data if the transaction commits with write concern “majority”."snapshot"
从多数提交数据的快照返回数据。"snapshot"
read concern provides no guarantee that read operations used a snapshot of majority-committed data."majority"
用于提交,“快照”读关注点不能保证读操作使用了多数提交数据的快照。"snapshot"
view of the data is synchronized across shards."snapshot"
视图是跨分片同步的。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:您可以在事务开始时设置事务级别写关注点:
w: 1
. w: 1
。Transactions support all write concern w values, including:事务支持所有写关注点w值,包括:
w: 1
¶w: 1
returns acknowledgement after the commit has been applied to the primary.w:1
在提交应用于主服务器后返回确认。
Important重要的
When you commit with 使用w: 1
, your transaction can be rolled back if there is a failover.w: 1
提交时,如果存在故障转移,则可以回滚事务。
w: 1
write concern, transaction-level "majority"
read concern provides no guarantees that read operations in the transaction read majority-committed data.w: 1
write concern, transaction-level "snapshot"
read concern provides no guarantee that read operations in the transaction used a snapshot of majority-committed data.w: "majority"
¶w: "majority"
returns acknowledgement after the commit has been applied to a majority (M) of voting members; i.e. the commit has been applied to the primary and (M-1) voting secondaries.w: "majority"
在承诺适用于多数(M)投票成员后返回确认;也就是说,提交已应用于主要和(M-1)投票辅助。w: "majority"
write concern, transaction-level "majority"
read concern guarantees that operations have read majority-committed data. w: "majority"
write concern, transaction-level "snapshot"
read concern guarantees that operations have from a synchronized snapshot of majority-committed data.w: "majority"
写入关注点进行提交时,事务级别的"snapshot"
读取关注点保证操作已从多数提交数据的同步快照中恢复。Note
Regardless of the write concern specified for the transaction, the commit operation for a sharded cluster transaction includes some parts that use 不管为事务指定的写关注点是什么,分片集群事务的提交操作都包括一些使用{w: "majority", j: true}
write concern.{w: "majority", j: true}
写关注点的部分。
For various production considerations with using transactions, see Production Considerations. 有关使用事务的各种生产注意事项,请参阅生产注意事项。In addition, or sharded clusters, see also Production Considerations (Sharded Clusters).此外,或分片群集,请参阅生产注意事项(分片群集)。
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.如果任何事务操作读取或写入包含仲裁器的分片,则其写入操作跨越多个分片的事务将出错并中止。
See also Disabled Read Concern Majority for transaction restrictions on shards that have disabled read concern majority.另请参阅禁用的读取关注多数,了解已禁用读取关注多数的碎片上的事务限制。
A 3-member PSA (Primary-Secondary-Arbiter) replica set or a sharded cluster with 3-member PSA shards may have disabled read concern majority (三成员PSA(主从仲裁器)副本集或具有三成员PSA碎片的分片群集可能已禁用读关注多数(--enableMajorityReadConcern false
or replication.enableMajorityReadConcern: false
)--enableMajorityReadConcern false
或replication.enableMajorityReadConcern: false
)
"snapshot"
for the transaction. "majority"
的碎片,则不能对该事务使用读关注点"snapshot"
。"local"
or "majority"
for the transaction. "local"
或"majority"
。"snapshot"
, the transaction errors and aborts."snapshot"
,事务将出错并中止。
"majority"
."majority"
的碎片,则其写操作跨越多个碎片的事务将出错并中止。You can specify read concern 即使在副本集中禁用了读取关注点"local"
or "majority"
or "snapshot"
even in the replica set has disabled read concern “majority”."majority"
,也可以指定读取关注点"local"
或"majority"
或"snapshot"
。
However, if you are planning to transition to a sharded cluster with disabled read concern majority shards, you may wish to avoid using read concern 但是,如果您计划过渡到具有禁用的读关注多数碎片的分片集群,您可能希望避免使用读关注"snapshot"
."snapshot"
(快照)。
Tip
To check if read concern “majority” is disabled, You can run 要检查读取关注点“多数”是否已禁用,可以在db.serverStatus()
on the mongod
instances and check the storageEngine.supportsCommittedReads
field. mongod
实例上运行db.serverStatus()
,并检查storageEngine.supportsCommittedReads
字段。If 如果为false
, read concern “majority” is disabled.false
,则禁用阅读关注"majority"
。
For more information, see 3-Member Primary-Secondary-Arbiter Architecture and Three Member Primary-Secondary-Arbiter Shards.有关更多信息,请参阅三成员主从仲裁器体系结构和三成员主从仲裁器碎片。
You cannot run transactions on a sharded cluster that has a shard with 不能在writeConcernMajorityJournalDefault
set to false
(such as a shard with a voting member that uses the in-memory storage engine).writeConcernMajorityJournalDefault
设置为false
的分片群集上运行事务(例如,使用内存存储引擎的投票成员的分片)。
Note
Regardless of the write concern specified for the transaction, the commit operation for a sharded cluster transaction includes some parts that use 不管为事务指定的写关注点是什么,分片集群事务的提交操作都包括一些使用{w: "majority", j: true}
write concern.{w: "majority", j: true}
写关注点的部分。
MongoDB provides various transactions metrics:MongoDB提供了各种事务度量:
Via | |
---|---|
db.serverStatus() methodserverStatus command |
Returns transactions metrics. |
$currentOp aggregation pipeline |
Returns:
|
db.currentOp() methodcurrentOp command |
Returns:
|
mongod and mongos log messages |
operationProfiling.slowOpThresholdMs threshhold) under the TXN log component.TXN 日志组件下有关慢速事务(即超过operationProfiling.slowOpThresholdMs 阈值的事务)的信息。 |
To use transactions, the featureCompatibilityVersion for all members of the deployment must be at least:要使用事务,部署的所有成员的featureCompatibilityVersion必须至少为:
featureCompatibilityVersion | |
---|---|
4.0 | |
4.2 |
To check the fCV for a member, connect to the member and run the following command:要检查fCV中是否有成员,请连接到该成员并运行以下命令:
For more information, see the 有关更多信息,请参阅setFeatureCompatibilityVersion
reference page.setFeatureCompatibilityVersion
参考页。
Starting in MongoDB 4.2, multi-document transactions are supported on replica sets and sharded clusters where:从MongoDB 4.2开始,在副本集和分片集群上支持多文档事务,其中:
In MongoDB 4.0, only replica sets using the WiredTiger storage engine supported transactions.在MongoDB 4.0中,只有使用WiredTiger存储引擎的副本集支持事务。
Note
You cannot run transactions on a sharded cluster that has a shard with 不能在writeConcernMajorityJournalDefault
set to false
, such as a shard with a voting member that uses the in-memory storage engine.writeConcernMajorityJournalDefault
设置为false
的分片群集上运行事务,例如使用内存存储引擎的投票成员的分片。