文档菜单
文档首页
/ / /
Rust 驱动
/

事务

在本页

  • 概述
  • 方法
  • 示例
  • 更多信息
  • API 文档

在本指南中,您可以学习如何使用Rust驱动来执行事务。事务允许您执行一系列操作,只有当整个事务提交时,数据才会改变。如果事务中的任何操作未成功,驱动程序将停止事务并丢弃所有更改,以防止它们在任何可见之前。这个特性称为原子性

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

当使用Rust驱动时,您可以从Client实例创建一个新的会话为ClientSession类型。您可以通过重用客户端来提高应用程序的性能,而不是每次都实例化一个新的客户端。

警告

仅在使用创建它的Client上运行的ClientSession操作中使用ClientSession。使用不同ClientClientSession会导致操作错误。

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

方法
描述
start_transaction()
在此会话上启动新的事务。必须将会话传递到事务中的每个操作中,否则操作将在事务之外运行。

您可以通过将TransactionOptions选项构建器方法链接到start_transaction()来设置事务选项。

在事务中运行的操作返回的错误可能包含一个 TRANSIENT_TRANSACTION_ERROR 标签,这表示整个事务可以被结束,然后可以期望成功的情况下重新尝试。
commit_transaction()
提交此会话的活动事务。如果会话中没有活动事务或事务之前已结束,则此方法返回错误。

此方法可能返回一个包含 UNKNOWN_TRANSACTION_COMMIT_RESULT 标签的错误,这表示无法确定提交的事务是否满足设置的写入关注。如果您遇到此错误,可以安全地重试提交,直到写入关注得到满足或方法返回不带此标签的错误。
abort_transaction()
结束此会话的活动事务。如果会话中没有活动事务或事务已被提交或结束,则此方法返回错误。
and_run()
运行给定的回调,然后提交或结束事务。如果回调抛出一个带有 TRANSIENT_TRANSACTION_ERROR 标签的错误,则驱动程序会重试回调和提交。如果它们抛出任何其他错误,则驱动程序会结束事务并将错误返回给调用者。当您使用此方法执行事务时,驱动程序会自动处理任何错误,因此您可以选择省略错误处理代码。

因为回调返回一个未来对象并且可以多次运行,所以 Rust 语言对捕获值的借用规则可能比较严格。因此,and_run() 方法接受一个上下文参数,该参数被传递给回调。

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

重要

可以在事务中运行的方法

要运行 MongoDB 事务中的操作,您必须将 session() 方法链接到操作。此方法接受一个 ClientSession 实例作为参数。

例如,要删除一个文档,您通常可以使用 delete_one() 方法。然而,要在一个事务中删除一个文档,您必须将 session() 方法链接到 delete_one() 并将会话作为参数传递。

以下代码定义了 insert_media() 回调函数,该函数将数据插入到 booksfilms 集合中

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(doc! {
"name": "Sula",
"author": "Toni Morrison"
})
.session(&mut *session)
.await?;
films_coll
.insert_one(doc! {
"name": "Nostalgia",
"year": 1983
})
.session(&mut *session)
.await?;
Ok(())
}

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

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

  2. 调用 start_transaction() 方法以启动事务。

  3. 调用 and_run() 方法在事务中运行 insert_media() 回调函数。

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

如果您需要更精确地控制您的交易,请参阅ClientSession API 文档,以找到如何手动创建和提交事务的示例。

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

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

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

要了解更多关于本指南中提到的方法和类型,请参阅以下 API 文档

返回

Atlas 搜索索引