对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

事务

在本指南中,您可以了解如何使用 Rust 驱动程序执行事务。事务允许您执行一系列操作,这些操作仅在整个事务提交后才会更改数据。如果事务中的任何操作不成功,驱动程序就会停止事务,并在所有数据更改变得可见之前予以丢弃。这种特征称为原子性

在 MongoDB 中,事务在逻辑会话中运行。 会话是要按顺序运行的一组相关读取或写入操作。 会话为一组操作启用因果一致性,并允许您在符合 ACID 的事务中运行操作,这是一个满足原子性、一致性、隔离性和持久性预期的事务。 MongoDB 保证事务操作中涉及的数据保持一致,即使操作遇到意外错误。

使用 Rust 驱动程序时,您可以从Client实例创建一个新会话,并将其类型定义为ClientSession 。 您可以将客户端重复用于多个会话和事务,而不是每次都实例化新客户端,从而提高应用程序的性能。

警告

仅在创建ClientSessionClient上运行的操作中使用 。 将ClientSession与不同的Client一起使用会导致操作错误。

Client实例上使用start_session()方法创建ClientSession 。 然后,您可以使用ClientSession类型提供的方法修改会话状态。 下表描述了这些方法:

方法
说明

start_transaction()

在该会话上启动新事务,并根据可选的 TransactionOptions 参数进行配置。必须将会话传递到事务中的每个操作,否则操作将在事务外运行。

从事务内运行的操作返回的错误可能包含 TRANSIENT_TRANSACTION_ERROR 标签,该标签表示可以结束整个事务,然后重试该事务,并预计将成功。

参数TransactionOptions

commit_transaction()

提交此会话的活动事务。如果此会话没有活动事务或事务已结束,则此方法返回错误。

此方法可能会返回包含 UNKNOWN_TRANSACTION_COMMIT_RESULT 标签的错误,这表示承诺的事务是否满足所设置的写关注(write concern)是未知的。如果遇到此错误,可以安全地重试承诺,直到满足写关注(write concern)或方法返回没有标签的错误。

abort_transaction()

结束此会话的活动事务。 如果该会话没有活动事务或者事务已提交或结束,则此方法将返回错误。

with_transaction()

在此会话上启动事务并运行给定的回调,然后提交或结束事务。当使用此方法执行事务时,驱动程序会自动处理任何错误,因此您可以选择省略错误处理代码。

由于回调返回未来并可以运行多次,因此 Rust 语言闭包借用捕获值的规则可能很受限制。因此,with_transaction() 方法接受传递给回调的上下文参数。

参数:上下文 C、回调 FnMut(&'a mut ClientSession, &'a mut C)TransactionOptions

重要

可在事务中运行的方法

要在事务中运行 MongoDB 任务,必须使用带有 _with_session() 后缀的方法。这些方法接受 ClientSession 实例作为参数。

例如,要删除文档,通常可以使用delete_one()方法。 但是,要在事务中删除文档,您必须使用delete_one_with_session()方法并将会话作为参数传递。

以下代码定义了将数据插入到booksfilmscollection的insert_media()回调:

async fn insert_media(session: &mut ClientSession) -> Result<(), Error> {
let books_coll = session
.client()
.database("db")
.collection::<Document>("books");
let films_coll = session
.client()
.database("db")
.collection::<Document>("films");
books_coll.insert_one_with_session(
doc! {
"name": "Sula",
"author": "Toni Morrison"
},
None,
session
).await?;
films_coll.insert_one_with_session(
doc! { "name": "Nostalgia", "year": 1983 },
None,
session
).await?;
Ok(())
}

以下代码完成以下操作以执行事务:

  1. 使用start_session()方法从客户端创建会话。

  2. 使用 with_transaction() 方法启动事务,并在事务中运行 insert_media() 回调函数。

let mut session = client.start_session(None).await?;
session
.with_transaction((), |session, _| insert_media(session).boxed(), None)
.await?;
println!("Successfully committed transaction!");
Successfully committed transaction!

如果您需要对事务进行更多控制,请参阅 ClientSession API文档 以查找示例如何手动创建和提交ACID 事务的示例。

要了解有关本指南中提到的概念的更多信息,请参阅服务器手册中的以下页面:

要学习;了解有关ACID compliance的更多信息,请参阅什么是数据库管理系统中的ACID属性? MongoDB网站上的文章。

要了解有关插入操作的更多信息,请参阅插入文档指南。

要进一步了解本指南所提及的方法和类型,请参阅以下 API 文档: