事务
概述
在本指南中,您可以了解如何使用Java驱动程序执行 事务。事务 允许您运行一系列操作,直到事务提交之前不会更改任何数据。如果事务中的任何操作返回错误,驱动程序将取消事务并丢弃所有更改,以确保更改不会变得可见。
在MongoDB中,事务在逻辑 会话 中运行。一个 会话 是一系列相关的读或写操作,您打算按顺序执行。会话使一组操作具有 因果一致性,或允许您执行 ACID事务。MongoDB保证事务操作涉及的数据保持一致性,即使操作遇到意外错误。
使用Java驱动程序时,您可以从MongoClient
实例创建一个新的 ClientSession
类型。我们建议您在多个会话和事务中重用客户端,而不是每次都实例化新的客户端。
警告
仅使用与创建它的 MongoClient
(或相关的 MongoDatabase
或 MongoCollection
)一起使用的 ClientSession
。使用与不同 MongoClient
一起使用的 ClientSession
将导致操作错误。
重要
您必须将 session
作为参数包含在您希望包含在事务中的任何操作中。
方法
通过在您的 MongoClient
实例上调用 startSession()
方法创建一个 ClientSession
。然后,您可以使用 ClientSession
提供的方法来修改会话状态。下表描述了您可以使用的方法来管理事务
方法 | 描述 |
---|---|
startTransaction() | 以默认事务选项为这个会话启动一个新的事务。通过将 TransactionOptions 的实例作为参数传递来以给定选项启动一个事务。如果会话中已经有一个活动事务正在运行,则不能启动事务。参数: TransactionOptions transactionOptions |
abortTransaction() | 结束这个会话的活跃事务。如果会话中没有活跃事务或者事务已经被结束,则返回一个错误。 |
commitTransaction() | 提交这个会话的活跃事务。如果会话中没有活跃事务或者事务已经被结束,则返回一个错误。 |
withTransaction() | 为这个会话启动一个新的事务并运行给定的函数。这个方法处理重试、提交和取消事务。通过将定义您想要在事务中执行的操作的 TransactionBody 的实例作为参数传递。参数: TransactionBody<T> transactionBody |
ClientSession
还有一些方法可以用来检索会话属性和修改可变会话属性。查看 API 文档 了解更多关于这些方法的信息。
示例
以下示例演示了您如何创建会话、创建事务,并通过以下步骤提交多文档插入操作:
通过使用
startSession()
方法从客户端创建会话。设置事务选项以配置事务行为。
使用
withTransaction()
方法启动事务。插入多个文档。当
withTransaction()
方法执行时,它将提交和取消事务。如果任何操作导致错误,则withTransaction()
将处理取消事务。
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 txnOptions = 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 }, txnOptions); } } catch (Exception e) { e.printStackTrace(); }
如果您需要更多对交易的控制,可以使用 startTransaction()
方法。您可以与上一节中描述的 commitTransaction()
和 abortTransaction()
方法一起使用此方法来手动管理事务的生命周期。
更多信息
要了解更多关于本指南中提到的概念,请参阅服务器手册中的以下页面
要了解更多关于ACID兼容性的信息,请参阅MongoDB网站上关于数据库管理系统中的ACID属性是什么?的文章。
API文档
要了解更多关于本指南中讨论的任何类型或方法,请参阅以下API文档