Transactions事务
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.对于分布式事务,事务可以跨多个操作、集合、数据库、文档和分片使用。
Transactions API事务API
➤ Use the Select your language drop-down menu in the upper-right to set the language of the following example.
This example highlights the key components of the transactions API. In particular, it uses the callback API. The callback API:本示例重点介绍了事务API的关键组件。特别是,它使用回调API。回调API:
-
starts a transaction启动事务 -
executes the specified operations执行指定的操作 -
commits the result (or aborts on error)提交结果(或出现错误时中止)
The callback API incorporates retry logic for certain errors. 回调API包含了针对某些错误的重试逻辑。The server tries to rerun the transaction after a TransientTransactionError or UnknownTransactionCommitResult commit error.服务器在TransientTransactionError
或UnknownTransactionCommitResult
提交错误后尝试重新运行事务。
Starting in MongoDB 6.2, the server does not retry the transaction if it receives a TransactionTooLargeForCache error.从MongoDB 6.2开始,如果服务器收到TransactionTooLargeForCache
错误,则不会重试该事务。
-
Recommended. Use the MongoDB driver updated for the version of your MongoDB deployment.推荐。使用为您的MongoDB部署版本更新的MongoDB驱动程序。For 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驱动程序。 -
When using the drivers, each operation in the transaction must be associated with the session (i.e. pass in the session to each operation).使用驱动程序时,事务中的每个操作都必须与会话相关联(即,将会话传递给每个操作)。 -
Operations in a transaction use transaction-level read concern, transaction-level write concern, and transaction-level read preference.事务中的操作使用事务级读取关注、事务级写入关注和事务级读取首选项。 -
In MongoDB 4.2 and earlier, you cannot create collections in transactions. Write operations that result in document inserts (e.g.在MongoDB 4.2及更早版本中,您不能在事务中创建集合。如果在事务内部运行,则导致文档插入的写入操作(例如,insert
or update operations withupsert: true
) must be on existing collections if run inside transactions.insert
或使用upsert:true
的更新操作)必须在现有集合上。 -
Starting in MongoDB 4.4, you can create collections in transactions implicitly or explicitly.从MongoDB 4.4开始,您可以隐式或显式地在事务中创建集合。See Create Collections and Indexes In a Transaction.请参见在事务中创建集合和索引。
//For a replica set, include the replica set name and a seedlist of the members in the URI string;对于副本集,在URI字符串中包括副本集名称和成员的种子列表;e.g.
// const uri = 'mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017/?replicaSet=myRepl'
//For a sharded cluster, connect to the mongos instances;对于分片集群,连接到mongos实例;e.g.
// const uri = 'mongodb://mongos0.example.com:27017,mongos1.example.com:27017/'
const client = new MongoClient(uri);
await client.connect();
//Prereq: Create collections.准备工作:创建集合。
await client
.db('mydb1')
.collection('foo')
.insertOne({ abc: 0 }, { writeConcern: { w: 'majority' } });
await client
.db('mydb2')
.collection('bar')
.insertOne({ xyz: 0 }, { writeConcern: { w: 'majority' } });
//Step 1: Start a Client Session步骤1:启动客户端会话
const session = client.startSession();
//Step 2: Optional. Define options to use for the transaction步骤2:可选。定义用于事务的选项
const transactionOptions = {
readPreference: 'primary',
readConcern: { level: 'local' },
writeConcern: { w: 'majority' }
};
//Step 3: Use withTransaction to start a transaction, execute the callback, and commit (or abort on error)步骤3:使用withTransaction启动事务、执行回调并提交(或在出现错误时中止)
//Note: The callback for withTransaction MUST be async and/or return a Promise.注意:withTransaction的回调必须是异步的和/或返回Promise。
try {
await session.withTransaction(async () => {
const coll1 = client.db('mydb1').collection('foo');
const coll2 = client.db('mydb2').collection('bar');
//Important:: You must pass the session to the operations重要提示:您必须将会话传递给操作
await coll1.insertOne({ abc: 1 }, { session });
await coll2.insertOne({ xyz: 999 }, { session });
}, transactionOptions);
} finally {
await session.endSession();
await client.close();
}Tip
See also:另请参阅:
For an example in有关mongosh
, seemongosh
Example.mongosh
中的示例,请参阅mongosh
示例。
Transactions and Atomicity事务和原子性Note
Distributed Transactions and Multi-Document Transactions分布式事务和多文档事务
Starting in MongoDB 4.2, the two terms are synonymous. Distributed transactions refer to multi-document transactions on sharded clusters and replica sets.从MongoDB 4.2开始,这两个术语是同义词。分布式事务是指分片集群和副本集上的多文档事务。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支持多文档事务:
- In version 4.0
, MongoDB supports multi-document transactions on replica sets.,MongoDB支持副本集上的多文档事务。- In version 4.2
, MongoDB introduces distributed transactions, which adds support for multi-document transactions on sharded clusters and incorporates the existing support for multi-document transactions on replica sets.,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):多文档事务是原子性的(即,提供一个“要么全有要么全无”的命题):
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例如,如果事务已提交,并且写1在分片a上可见,但写2在分片B上还不可见,则外部读取时读取关注"local"
can read the results of write 1 without seeing write 2."local"
可以读取写1的结果,而不会看到写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, 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.有关其他事务使用注意事项(如运行时限制和操作日志大小限制),请参阅生产注意事项。Tip
See also:另请参阅:
Transactions and Operations事务和操作
Distributed transactions can be used across multiple operations, collections, databases, documents, and, starting in MongoDB 4.2, shards.分布式事务可以跨多个操作、集合、数据库、文档使用,从MongoDB 4.2开始,还可以跨分片使用。
For transactions:对于事务:
You can specify read/write (CRUD) operations on existing collections.您可以在现有集合上指定读/写(CRUD)操作。For a list of CRUD operations, see CRUD Operations.有关CRUD操作的列表,请参阅CRUD操作。Starting in MongoDB 4.4, you can create collections and indexes in transactions.从MongoDB 4.4开始,您可以在事务中创建集合和索引。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.例如,如果您在一个分片中写入一个现有集合,并在另一个分片中隐式创建一个集合,则MongoDB无法在同一事务中执行这两个操作。You cannot write to capped collections. (Starting in MongoDB 4.2)您不能写入封顶集合。(从MongoDB 4.2开始)You cannot use read concern从封顶集合中读取时,不能使用读取关注"snapshot"
when reading from a capped collection. (Starting in MongoDB 5.0)"snapshot"
。(从MongoDB 5.0开始)You cannot read/write to collections in the无法读取/写入config
,admin
, orlocal
databases.config
、admin
或local
数据库中的集合。You cannot write to无法写入system.*
collections.system.*
集合。You cannot return the supported operation's query plan (i.e.无法返回支持的操作的查询计划(即explain
).explain
)。
For cursors created outside of a transaction, you cannot call对于在事务外部创建的游标,不能在事务内部调用getMore
inside the transaction.getMore
。For cursors created in a transaction, you cannot call对于在事务中创建的游标,不能在事务外调用getMore
outside the transaction.getMore
。
Starting in MongoDB 4.2, you cannot specify从MongoDB 4.2开始,您不能将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"
的创建或删除操作,以确保事务可以获取所需的锁。Tip
See also:另请参阅:
Create Collections and Indexes In a Transaction在事务中创建集合和索引
Starting in MongoDB 4.4, you can perform the following operations inside of a multi-document transaction as long as the transaction is not a cross-shard write transaction:从MongoDB 4.4开始,只要事务不是跨分片写事务,就可以在多文档事务内部执行以下操作:
Create collections.创建集合。Create indexes on new empty collections created earlier in the same transaction.对先前在同一事务中创建的新的空集合创建索引。
In MongoDB 4.2 and earlier, operations that affect the database catalog, such as creating or dropping a collection or an index, are disallowed in transactions.在MongoDB 4.2及更早版本中,事务中不允许执行影响数据库目录的操作,例如创建或删除集合或索引。
When creating a collection inside a transaction:在事务中创建集合时:
You can implicitly create a collection, such as with:您可以隐式创建集合,例如使用:
an insert operation against a non-existing collection, or针对不存在的集合的插入操作,或者an update/findAndModify operation with针对不存在的集合执行upsert: true
against a non-existing collection.upsert:true
的update
/findAndModify
操作。You can explicitly create a collection using the可以使用create
command or its helperdb.createCollection()
.create
命令或其助手db.createCollection()
显式创建集合。
When creating an index inside a transaction [1], the index to create must be on either:在事务中创建索引时[1],要创建的索引必须位于以下任一位置:
a non-existing collection.不存在的集合。The collection is created as part of the operation.集合是作为操作的一部分创建的。a new empty collection created earlier in the same transaction.在同一事务的早期创建的新的空集合。
[1] You can also run您还可以对现有索引运行db.collection.createIndex()
anddb.collection.createIndexes()
on existing indexes to check for existence.db.collection.createIndex()
和db.collection.createIndexes()
来检查是否存在。These operations return successfully without creating the index.这些操作在不创建索引的情况下成功返回。
Restrictions限制
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无法在同一事务中执行这两个操作。For explicit creation of a collection or an index inside a transaction, the transaction read concern level must be对于在事务内显式创建集合或索引,事务读取关注级别必须为"local"
."local"
。Explicit creation is through:显式创建是通过:
Command命令Method方法create
db.createCollection()
createIndexes
db.collection.createIndex()
db.collection.createIndexes()
Tip
See also:另请参阅:
Count Operation计数操作
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驱动程序提供了一个集合级APIcountDocuments(filter, options)
as a helper method that uses the$group
with a$sum
expression to perform a count. The 4.0 drivers have deprecated thecount()
API.countDocuments(filter, options)
作为一个助手方法,使用带有$sum
表达式的$group
来执行计数。4.0驱动程序已弃用count()
API。
Starting in MongoDB 4.0.3,从MongoDB 4.0.3开始,mongosh
provides thedb.collection.countDocuments()
helper method that uses the$group
with a$sum
expression to perform a count.mongosh
提供了db.collection.countDocuments()
辅助方法,该方法使用带有$sum
表达式的$group
来执行计数。
Distinct Operation剔除重复项操作
To perform a distinct operation within a transaction:要在事务中执行剔除重复项操作:
For unsharded collections, you can use the对于未排序的集合,可以使用db.collection.distinct()
method/thedistinct
command as well as the aggregation pipeline with the$group
stage.db.collection.distinct()
方法/distinct
命令以及带有$group
阶段的聚合管道。For sharded collections, you cannot use the对于分片集合,不能使用db.collection.distinct()
method or thedistinct
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:例如:
Instead of不使用db.coll.distinct("x")
, usedb.coll.distinct("x")
,而是使用db.coll.aggregate([
{ $group: { _id: null, distinctValues: { $addToSet: "$x" } } },
{ $project: { _id: 0 } }
])Instead of不使用db.coll.distinct("x", { status: "A" })
, use:db.coll.distinct("x", { status: "A" })
,而是使用: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 Operations信息操作
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.hello
、buildInfo
、connectionStatus
(及其辅助方法);但是,它们不能是事务中的第一个操作。
Restricted Operations受限操作
Changed in version 4.44.4版更改.
The following operations are not allowed in transactions:事务记录中不允许执行以下操作:
Operations that affect the database catalog, such as creating or dropping a collection or an index when using MongoDB 4.2 or lower.影响数据库目录的操作,例如在使用MongoDB 4.2或更低版本时创建或删除集合或索引。Starting in MongoDB 4.4, you can create collections and indexes in transactions unless the transaction is a cross-shard write transaction.从MongoDB 4.4开始,您可以在事务中创建集合和索引,除非事务是跨分片写入事务。For details, see Create Collections and Indexes In a Transaction.有关详细信息,请参阅在事务中创建集合和索引。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.例如,如果您在一个分片中写入一个现有集合,并在另一个分片中隐式创建一个集合,则MongoDB无法在同一事务中执行这两个操作。Explicit creation of collections, e.g.当使用“local”以外的读取关注级别时,显式创建集合,例如db.createCollection()
method, and indexes, e.g.db.collection.createIndexes()
anddb.collection.createIndex()
methods, when using a read concern level other than"local"
.db.createCollection()
方法,以及索引,例如db.collection.createIndexes()
和db.collection.createIndex()
方法。ThelistCollections
andlistIndexes
commands and their helper methods.listCollections
和listIndexes
命令及其辅助方法。Other non-CRUD and non-informational operations, such as其他非CRUD和非信息性操作,如createUser
,getParameter
,count
, etc. and their helpers.createUser
、getParameter
、count
等及其助手。
Transactions and Sessions事务和会话
Transactions are associated with a session; i.e. you start a transaction for 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.如果会话结束并且有一个打开的事务,则该事务将中止。
Read Concern/Write Concern/Read Preference读取关注/写入关注/读取首选项
Transactions and Read Preference事务和读取首选项
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:使用驱动程序,您可以在事务开始时设置事务级别的读取首选项:
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默认情况下,客户端级别的读取首选项是primary
.primary
。
Multi-document transactions that contain read operations must use read preference包含读取操作的多文档事务必须使用读取首选项primary
. All operations in a given transaction must route to the same member.primary
。给定事务中的所有操作都必须路由到同一成员。
Transactions and Read Concern事务和读取关注
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默认情况下,客户端级别的读取关注是针对主服务器的读取的"local"
for reads against the primary."local"
。See also:另请参阅:
Transactions support the following read concern levels:事务支持以下读取关注级别:
"local"
Read concern读取关注"local"
returns the most recent data available from the node but can be rolled back."local"
返回节点中可用的最新数据,但可以回滚。For transactions on sharded cluster,对于分片集群上的事务,"local"
read concern cannot guarantee that the data is from the same snapshot view across the shards."local"
读取关注不能保证数据来自分片之间的同一快照视图。If snapshot isolation is required, use如果需要快照隔离,请使用"snapshot"
read concern."snapshot"
读取关注。Starting in MongoDB 4.4, you can create collections and indexes inside a transaction.从MongoDB 4.4开始,您可以在事务中创建集合和索引。If explicitly creating a collection or an index, the transaction must use read concern如果显式创建集合或索引,则事务必须使用读取关注"local"
."local"
。Implicit creation of a collection can use any of the read concerns available for transactions.隐式创建集合可以使用任何可用于事务的读取关注。
"majority"
Read concern如果事务以写入关注"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"
返回已被大多数副本集成员确认的数据(即数据无法回滚)。If the transaction does not use write concern "majority" for the commit, the如果事务不使用写入关注"majority"
read concern provides no guarantees that read operations read majority-committed data."majority"
进行提交,则"majority"
读取关注不能保证读取操作读取多数提交的数据。For transactions on sharded cluster,对于分片集群上的事务,"majority"
read concern cannot guarantee that the data is from the same snapshot view across the shards."majority"
读取关注不能保证数据来自分片之间的同一快照视图。If snapshot isolation is required, use如果需要快照隔离,请使用"snapshot"
read concern."snapshot"
读取关注。
"snapshot"
Read concern如果事务以写入关注"snapshot"
returns data from a snapshot of majority committed data if the transaction commits with write concern "majority"."majority"
提交,则读取关注"snapshot"
从多数提交数据的快照中返回数据。If the transaction does not use write concern "majority" for the commit, the如果事务不使用写入关注"snapshot"
read concern provides no guarantee that read operations used a snapshot of majority-committed data."majority"
进行提交,则"snapshot"
读取关注不能保证读取操作使用了多数提交数据的快照。For transactions on sharded clusters, the对于分片集群上的事务,数据的"snapshot"
view of the data is synchronized across shards."snapshot"
视图在分片之间同步。
Transactions and Write Concern事务和写入关注
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:如果事务级写入关注和会话级写入关注未设置,则事务级写事项默认为客户端级写入关注:
MongoDB 5.0及更高版本中的w: "majority"
in MongoDB 5.0 and later, with differences for deployments containing arbiters.w: "majority"
,与包含仲裁器的部署不同。See Implicit Default Write Concern.请参阅隐式默认写入关注。w: 1
in MongoDB 4.4 and earlier.在MongoDB 4.4及更早版本中。Tip
See also:另请参阅:
Default MongoDB Read Concerns/Write Concerns默认MongoDB读取关注/写入关注
Transactions support all write concern w values, including:事务支持所有写入关注w值,包括:
w: 1
Write concern写入关注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
提交时,如果存在故障转移,则可以回滚事务。When you commit with当您使用w: 1
write concern, transaction-level"majority"
read concern provides no guarantees that read operations in the transaction read majority-committed data.w: 1
写入关注进行提交时,事务级别的"majority"
读取关注不能保证事务中的读取操作读取多数提交的数据。When you commit with当您使用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: 1
写入关注进行提交时,事务级别的"snapshot"
读取关注不能保证事务中的读取操作使用大多数提交数据的快照。
w: "majority"
Write concern写入关注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)有投票权的成员后,返回确认;即提交已应用于primary和(M-1)个有投票权的secondary。When you commit with当您使用w: "majority"
write concern, transaction-level"majority"
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.w: "majority"
写入关注进行提交时,事务级别的"majority"
读取关注可以保证操作读取了多数提交的数据。对于分片集群上的事务,大多数提交数据的视图不会在分片之间同步。When you commit with当您使用w: "majority"
write concern, transaction-level"snapshot"
read concern guarantees that operations have read 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}
写入关注的部分。
The server parameter服务器参数coordinateCommitReturnImmediatelyAfterPersistingDecision
controls when transaction commit decisions are returned to the client.coordinateCommitReturnImmediatelyAfterPersistingDecision
控制何时将事务提交决策返回到客户端。
The parameter was introduced in MongDB 5.0 with a default value of该参数是在MongDB 5.0中引入的,默认值为true
.true
。In MongoDB 6.1 the default value changes to在MongoDB 6.1中,默认值更改为false
.false
。
When当coordinateCommitReturnImmediatelyAfterPersistingDecision
isfalse
, the shard transaction coordinator waits for all members to acknowledge a multi-document transaction commit before returning the commit decision to the client.coordinateCommitReturnImmediatelyAfterPersistingDecision
为false
时,分片事务协调器会等待所有成员确认多文档事务提交,然后再将提交决定返回给客户端。
If you specify a如果为多文档事务指定了"majority"
write concern for a multi-document transaction and the transaction fails to replicate to the calculated majority of replica set members, then the transaction may not immediately roll back on replica set members."majority"
写入问题,而该事务未能复制到计算出的多数副本集成员,则该事务可能不会立即回滚到副本集成员。The replica set will be eventually consistent.复制副本集最终将保持一致。A transaction is always applied or rolled back on all replica set members.事务总是在所有复制集成员上应用或回滚。
Regardless of the write concern specified for the transaction, the driver applies无论为事务指定的写入关注是什么,当重试w: "majority"
as the write concern when retryingcommitTransaction
.commitTransaction
时,驱动程序都会应用w: "majority"
作为写入关注。
General Information一般信息
Production Considerations生产注意事项
For various production considerations with using transactions, see Production Considerations.有关使用事务的各种生产注意事项,请参阅生产注意事项。In addition, for sharded clusters, see also Production Considerations (Sharded Clusters).此外,对于分片集群,请参阅生产注意事项(分片集群)。
Arbiters仲裁器
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.如果任何事务操作从包含仲裁器的分片中读取或写入,则写入操作跨多个分片的事务将出错并中止。
Shard Configuration Restriction分片配置限制
You cannot run transactions on a sharded cluster that has a shard with您不能在具有writeConcernMajorityJournalDefault
set tofalse
(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}
写入关注的部分。
Diagnostics诊断
MongoDB provides various transactions metrics:MongoDB提供了各种事务度量:
Source来源Returns返回db.serverStatus()
method方法
serverStatus
command命令Returns transactions metrics.返回事务度量。$currentOp
aggregation pipeline聚合管道Returns:返回:
$currentOp.transaction
if an operation is part of a transaction.如果操作是事务的一部分。Information on inactive sessions that are holding locks as part of a transaction.关于作为事务一部分持有锁的非活动会话的信息。$currentOp.twoPhaseCommitCoordinator
metrics for sharded transactions that involes writes to multiple shards.调用对多个分片的写入的分片事务的度量。db.currentOp()
method方法
currentOp
command命令Returns:返回:
currentOp.transaction
if an operation is part of a transaction.如果操作是事务的一部分。currentOp.twoPhaseCommitCoordinator
metrics for sharded transactions that involes writes to multiple shards.调用对多个分片的写入的分片事务的度量。mongod
and和mongos
log messages日志消息Includes information on slow transactions (i.e. transactions that exceed the在operationProfiling.slowOpThresholdMs
threshold) under theTXN
log component.TXN
日志组件下包括有关慢速事务(即超过operationProfiling.slowOpThresholdMs
阈值的事务)的信息。
Feature Compatibility Version (fCV)功能兼容性版本(fCV)
To use transactions, the featureCompatibilityVersion for all members of the deployment must be at least:若要使用事务,部署的所有成员的featureCompatibilityVersion
必须至少为:
Deployment部署Minimum下限featureCompatibilityVersion
Replica Set 4.0
Sharded Cluster 4.2
To check the fCV for a member, connect to the member and run the following command:若要检查成员的fCV,请连接到该成员并运行以下命令:db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )
For more information, see the有关更多信息,请参阅setFeatureCompatibilityVersion
reference page.setFeatureCompatibilityVersion
参考页。
Storage Engines存储引擎
Starting in MongoDB 4.2, multi-document transactions are supported on replica sets and sharded clusters where:从MongoDB 4.2开始,副本集和分片集群支持多文档事务,其中:
the primary uses the WiredTiger storage engine, and主存储使用WiredTiger存储引擎,并且the secondary members use either the WiredTiger storage engine or the in-memory storage engines.次要成员使用WiredTiger存储引擎或内存中存储引擎。
In MongoDB 4.0, only replica sets using the WiredTiger storage engine support transactions.在MongoDB 4.0中,只有使用WiredTiger存储引擎的副本集才支持事务。Note
You cannot run transactions on a sharded cluster that has a shard with不能在具有writeConcernMajorityJournalDefault
set tofalse
, such as a shard with a voting member that uses the in-memory storage engine.writeConcernMajorityJournalDefault
设置为false
的分片的分片集群上运行事务,例如具有使用内存存储引擎的投票成员的分片。
Limit Critical Section Wait Time限制关键部分等待时间
Starting in MongoDB 5.2 (and 5.0.4):从MongoDB 5.2(和5.0.4)开始:
When a query accesses a shard, a chunk migration or DDL operation may hold the critical section for the collection.当查询访问分片时,区块迁移或DDL操作可能会保留集合的关键部分。To limit the time a shard waits for a critical section within a transaction, use the要限制分片等待事务中关键部分的时间,请使用metadataRefreshInTransactionMaxWaitBehindCritSecMS
parameter.metadataRefreshInTransactionMaxWaitBehindCritSecMS
参数。
Additional Transactions Topics其他事务主题
Drivers API驱动程序APIProduction Considerations生产注意事项Production Considerations (Sharded Clusters)生产注意事项(分片集群)Transactions and Operations事务和操作To learn more about when to use transactions and if they support your use case, see the Are Transactions Right For You?要了解有关何时使用事务以及它们是否支持您的用例的更多信息,请参阅事务是否适合您?presentation from MongoDB.live 2020.
MongoDB Live 2020的演示。