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

事务

在本指南中,您可以了解如何使用 Java 驱动程序执行事务事务允许您运行一系列操作,这些操作在提交事务之前不会更改任何数据。如果事务中的任何操作返回错误,驱动程序就会取消事务,并在所有数据更改变得可见之前将其丢弃。

在MongoDB中,事务在逻辑会话中运行。会话是您打算按顺序运行的一组相关读取或写入操作。会话允许您在符合ACID的ACID 事务中运行操作,该ACID 事务满足原子性、一致性、隔离性和持久性的预期。

使用Java驱动程序时,您可以从 MongoClient实例创建一个新会话,并将其类型定义为 ClientSession。我们建议您将客户端重复用于多个会话和事务,而不是每次都实例化一个新客户端。

警告

仅应将 ClientSession 与创建它的 MongoClient(或关联的 MongoDatabaseMongoCollection)一起使用。将 ClientSession 与其他 MongoClient 一起使用会导致操作错误。

重要

对于要包含在ACID 事务中的任何操作,必须包含session作为参数。

MongoDB在某些客户端会话中实现因果一致性。因果一致性模型ACID 一致性保证在分布式系统中,会话中的操作按因果顺序运行。客户端观察到的结果与因果关系或操作之间的依赖关系一致。示例,如果您执行一系列操作,其中一个操作在逻辑上依赖于另一个操作的结果,则任何后续读取都会反映这种依赖关系。

为了保证因果一致性,客户端端会话必须满足以下要求:

  • 启动会话时,驱动程序必须启用因果一致性选项。该选项默认启用。

  • 操作必须在单个线程的单个会话中运行。否则,会话或线程必须相互传达optime和集群时间值。 要查看传达这些值的两个会话的示例,请参阅MongoDB Server手册中的因果一致性示例

  • 您必须使用 MAJORITY读关注(read concern)。

  • 您必须使用 MAJORITY写关注(write concern)。这是默认的写关注(write concern)值。

下表描述了因果一致会话提供的ACID 一致性保证:

保证
说明

读取写入操作

读取操作会反映之前写入操作的结果。

单调读取

读取操作不会返回反映比先前读取操作更早的数据状态的结果。

单调写入

如果写入操作必须先于其他写入操作,则服务器会先运行此写入操作。

示例,如果调用 insertOne() 插入文档,然后调用 updateOne() 修改插入的文档,则服务器首先运行插入操作。

读取后写入

如果写入操作必须在其他读取操作之后执行,服务器会先执行读取操作。

示例,如果您调用 find() 来检索文档,然后调用 deleteOne() 来删除检索到的文档,则服务器会先运行查找操作。

提示

要学习;了解有关本节中提到的概念的更多信息,请参阅以下MongoDB Server手册条目:

MongoClient实例上使用startSession()方法创建ClientSession 。 然后,您可以使用ClientSession提供的方法修改会话状态。 下表描述了可用于管理ACID 事务的方法:

方法
说明

startTransaction()

使用默认ACID 事务选项为此会话启动新ACID 事务。将TransactionOptions 的实例作为参数传递,以使用给定选项启动ACID 事务。如果会话中已运行活动ACID 事务,则无法启动ACID

事务。参数:TransactionOptions transactionOptions

abortTransaction()

结束此会话的ACID 事务事务。 如果该会话没有活动ACID 事务或ACID 事务先前已结束,则返回错误。

commitTransaction()

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

withTransaction()

为此会话启动新ACID 事务并运行给定函数。此方法处理重试、提交和中止事务。将TransactionBody 的实例作为参数传递,该参数定义要在ACID

事务中执行的操作。参数:TransactionBody<T> transactionBody

ClientSession还提供检索会话属性和修改可变会话属性的方法。 查看API文档以学习;了解有关这些方法的更多信息。

提示

事务超时

您可以在事务中设立操作完成所需的时间限制。要学习;了解更多信息,请参阅《限制服务器执行时间》指南中的“事务”部分。

以下示例演示了如何通过以下步骤创建会话、创建ACID 事务以及提交多文档插入操作:

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

  2. 设置ACID 事务选项以配置ACID 事务行为。

  3. 使用 withTransaction() 方法启动事务。

  4. 插入多个文档。 withTransaction()方法执行、提交和中止ACID 事务。 如果任何操作导致错误, withTransaction()将处理取消ACID 事务。

String connectionString = "<connection string>"; // Replace with your connection string
try (MongoClient mongoClient = MongoClients.create(connectionString)) {
MongoDatabase database = mongoClient.getDatabase("transaction_db");
MongoCollection<Document> collection = database.getCollection("books");
// Sets transaction options
TransactionOptions transactionOptions = TransactionOptions.builder()
.writeConcern(WriteConcern.MAJORITY)
.build();
try (ClientSession session = mongoClient.startSession()) {
// Uses withTransaction and lambda for transaction operations
session.withTransaction(() -> {
collection.insertMany(session, Arrays.asList(
new Document("title", "The Bluest Eye").append("author", "Toni Morrison"),
new Document("title", "Sula").append("author", "Toni Morrison"),
new Document("title", "Song of Solomon").append("author", "Toni Morrison")
));
return null; // Return value as expected by the lambda
}, transactionOptions);
}
} catch (Exception e) {
e.printStackTrace();
}

如果需要更好地控制事务,可以使用startTransaction()方法。 您可以将此方法与上一节中描述的commitTransaction()abortTransaction()方法结合使用,以手动管理ACID 事务生命周期。

注意

不支持并行操作

Java驱动程序不支持在单个事务中运行并行操作。

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

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

要查看在示例应用程序中运行多文档ACID事务的教程,请参阅教程:运行多文档ACID事务。

要进一步了解本指南所讨论的任何类型或方法,请参阅以下 API 文档: