事务
Overview
在本指南中,您可以学习;了解如何使用Java驾驶员来执行事务。 事务允许您运行一系列操作,这些操作在提交ACID 事务之前不会更改任何数据。 如果ACID 事务中的任何操作返回错误,驾驶员就会取消ACID 事务,并在所有数据更改变得可见之前将其丢弃。
在MongoDB中,事务在逻辑会话中运行。会话是您打算按顺序运行的一组相关读取或写入操作。会话允许您在符合ACID的ACID 事务中运行操作,该ACID 事务满足原子性、一致性、隔离性和持久性的预期。
使用Java驾驶员时,您可以从 MongoClient
实例创建一个新会话,并将其类型定义为ClientSession
。 我们建议您将客户端重复用于多个会话和事务,而不是每次都实例化一个新客户端。
警告
仅应将 ClientSession
与创建它的 MongoClient
(或关联的 MongoDatabase
或 MongoCollection
)一起使用。将 ClientSession
与其他 MongoClient
一起使用会导致操作错误。
重要
对于要包含在ACID 事务中的任何操作,必须包含session
作为参数。
因果一致性(Causal Consistency)
MongoDB在某些客户端会话中实现因果一致性。因果一致性模型ACID 一致性保证在分布式系统中,会话中的操作按因果顺序运行。客户端观察到的结果与因果关系或操作之间的依赖关系一致。示例,如果您执行一系列操作,其中一个操作在逻辑上依赖于另一个操作的结果,则任何后续读取都会反映这种依赖关系。
为了保证因果一致性,客户端端会话必须满足以下要求:
启动会话时,驾驶员必须启用因果一致性选项。该选项默认启用。
操作必须在单个线程的单个会话中运行。否则,会话或线程必须相互传达操作时间和集群时间值。要查看传达这些值的两个会话的示例,请参阅MongoDB Server手册中的因果一致性示例。
您必须使用
MAJORITY
读关注(read concern)。您必须使用
MAJORITY
写关注(write concern)。这是默认的写关注(write concern)值。
下表描述了因果一致会话提供的ACID 一致性保证:
保证 | 说明 |
---|---|
读取写入操作 | 读取操作会反映之前写入操作的结果。 |
单调读取 | 读取操作不会返回反映比先前读取操作更早的数据状态的结果。 |
单调写入 | 如果写入操作必须先于其他写入操作,则服务器会先运行此写入操作。 示例,如果调用 |
读取后写入 | 如果写入操作必须在其他读取操作之后执行,服务器会先执行读取操作。 示例,如果您调用 |
提示
要学习;了解有关本节中提到的概念的更多信息,请参阅以下MongoDB Server手册条目:
方法
在MongoClient
实例上使用startSession()
方法创建ClientSession
。 然后,您可以使用ClientSession
提供的方法修改会话状态。 下表描述了可用于管理ACID 事务的方法:
方法 | 说明 |
---|---|
| Starts a new transaction for this session with the
default transaction options. Pass an instance of TransactionOptions
as a parameter to start a transaction with given options. You
cannot start a transaction if there's already an active transaction
running in the session.Parameter: TransactionOptions transactionOptions |
| Ends the active transaction for this session. Returns an error
if there is no active transaction for the
session or the transaction was previously ended. |
| Commits the active transaction for this session. Returns an
error if there is no active transaction for the session or if the
transaction was ended. |
| Starts a new transaction for this session and runs the given function. This
method handles retries, committing, and aborting transactions. Pass an
instance of TransactionBody as a parameter that defines the
operations you want to execute within the transaction.Parameter: TransactionBody<T> transactionBody |
ClientSession
还提供检索会话属性和修改可变会话属性的方法。 查看API文档以学习;了解有关这些方法的更多信息。
例子
以下示例演示了如何通过以下步骤创建会话、创建ACID 事务以及提交多文档插入操作:
使用
startSession()
方法从客户端创建会话。设置ACID 事务选项以配置ACID 事务行为。
使用
withTransaction()
方法启动事务。插入多个文档。
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 事务中运行并行操作。
更多信息
要了解有关本指南中提到的概念的更多信息,请参阅服务器手册中的以下页面:
要学习;了解有关ACID compliance的更多信息,请参阅什么是数据库管理系统中的ACID属性? MongoDB网站上的文章。
API 文档
要进一步了解本指南所讨论的任何类型或方法,请参阅以下 API 文档: