对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
MongoDB Branding Shape
Click here >
Docs 菜单

事务中的批量操作

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

MongoDB 保证事务操作中涉及的数据保持一致,即使操作遇到意外错误。

在MongoDB中,事务在逻辑会话中运行。会话是您打算按顺序运行的一组相关读取或写入操作。会话启用一群组操作的因果一致性,或者允许您在ACID transaction中执行操作。

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

以下示例展示了如何通过调用 StartSession() 方法来创建会话:

var client = new MongoClient("mongodb://localhost:27017");
var session = client.StartSession();

警告

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

您可以通过将 ClientSessionOptions 类的实例传递给 StartSession() 方法来自定义会话行为。下表描述了可以在 ClientSessionOptions对象上设立的属性:

属性
说明

CausalConsistency



指定会话是否因果一致。在因果一致的会话中,驾驶员按照操作的发出顺序执行操作。要学习;了解更多信息,请参阅因果一致性。数据类型:boolean
默认值:true

DefaultTransactionOptions

指定会话的默认ACID 事务选项。这包括最大提交时间、读关注(read concern)、读取偏好(read preference)和写关注(write

concern)。数据类型:TransactionOptions
默认值:null

Snapshot

指定驾驶员是否执行快照读取。要学习;了解有关快照读取的更多信息,请参阅MongoDB

Server手册中的读关注“快照”。数据类型:boolean
默认值:false

SnapshotTime

指定驾驶员读取会话中所有数据的集群时间。设置此属性时,必须将Snapshot 设立为true 。要学习;了解更多信息,请参阅MongoDB

Server手册中的读关注“快照”。数据类型:BsonTimestamp
默认值:null

DefaultTransactionOptions属性接受 TransactionOptions 类的实例。下表描述了可以在 TransactionOptions对象上设立的属性:

属性
说明

MaxCommitTime

单个commitTransaction 命令可以运行的最长时间。如果提交超过此限制, MongoDB Server将返回MaxTimeMSExpired 错误并且不会提交ACID 事务中的更改。出现此错误后,驾驶员不会重试提交。如果省略此属性,

MongoDB Server将应用默认ACID

事务运行时限制。数据类型:TimeSpan?
默认值:null

ReadConcern

会话中每个ACID 事务的读关注。要学习;了解更多信息,请参阅MongoDB Server手册中的读关注。如果省略此属性,则事务将使用会话级读关注(read

concern)(如果您设立了该属性)。如果您还省略了会话级读关注(read concern),则事务将使用客户端级读关注(read

concern)。数据类型:ReadConcern
默认值:null

ReadPreference

会话中每个ACID 事务的读取偏好。要学习;了解更多信息,请参阅MongoDB Server手册中的读取偏好。如果省略此属性,则事务将使用会话级读取偏好(read

preference)(如果您设立了该偏好)。如果您还省略了会话级别的读取偏好(read preference),则事务将使用客户端级别的读取偏好(read

preference)。数据类型:ReadPreference
默认值:null

WriteConcern

为会话中的每个ACID 事务写入关注。要学习;了解更多信息,请参阅MongoDB Server手册中的写关注。如果省略此属性,则事务将使用会话级写关注(write

concern)(如果您设立了该写关注)。如果您还省略了会话级写关注(write concern),则事务将使用客户端级写关注(write

concern)。数据类型:WriteConcern
默认值:null

以下代码示例展示了如何使用自定义选项创建会话:

var client = new MongoClient("mongodb://localhost:27017");
var sessionOptions = new ClientSessionOptions
{
CausalConsistency = true,
DefaultTransactionOptions = new TransactionOptions(
readConcern: ReadConcern.Available,
writeConcern: WriteConcern.Acknowledged)
};
var session = client.StartSession(sessionOptions);

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

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

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

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

  • 您必须使用 ReadConcern.Majority读关注(read concern)。

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

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

保证
说明

读取写入操作

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

单调读取

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

单调写入

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

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

读取后写入

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

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

提示

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

MongoClient 实例上使用同步 StartSession() 或异步 StartSessionAsync() 方法创建 IClientSession。然后,您可以使用 IClientSession 接口提供的方法集来修改会话状态。从以下 Synchronous MethodsAsynchronous Methods 标签页中进行选择,了解管理事务的方法:

方法
说明

StartTransaction()

在此会话上启动使用给定选项配置的新ACID 事务。如果会话已存在正在进行的ACID 事务,则会引发异常。要学习;了解有关此方法的更多信息,请参阅服务器手册中的 startTransaction() 页面。参数:

TransactionOptions(可选)

AbortTransaction()

结束此会话的ACID 事务。如果会话没有ACID 事务或者ACID 事务已提交或结束,则会引发异常。要学习;了解有关此方法的更多信息,请参阅服务器手册中的 abortTransaction() 页面。参数:

CancellationToken

CommitTransaction()

提交此会话的ACID 事务。如果会话没有ACID 事务或ACID 事务已结束,则会引发异常。要学习;了解有关此方法的更多信息,请参阅服务器手册中的 commitTransaction()

页面。参数:CancellationToken

WithTransaction()

在此会话上启动事务并运行给定的回调。要了解有关此方法的更多信息,请参阅服务器手册中的 withTransaction() 页面

重要提示:在 WithTransaction()使用的回调函数中捕获异常时,必须在退出 try-catch区块之前重新抛出异常。否则可能会导致无限循环。 有关如何处理这种情况下的异常的更多详细信息,请参阅《服务器》手册中的“事务”,并从语言下拉列表中选择 C#以查看示例。


参数:Func <IClientSessionHandle, CancellationToken, Task<TResult>>TransactionOptionsCancellationToken
返回类型:Task <TResult>

方法
说明

StartTransaction()

在此会话上启动使用给定选项配置的新ACID 事务。如果会话已存在正在进行的ACID 事务,则会引发异常。要学习;了解有关此方法的更多信息,请参阅服务器手册中的 startTransaction() 页面。参数:

TransactionOptions(可选)

AbortTransactionAsync()

结束此会话的ACID 事务。如果会话没有ACID 事务或者ACID 事务已提交或结束,则会引发异常。要学习;了解有关此方法的更多信息,请参阅服务器手册中的 abortTransaction() 页面。参数:

CancellationToken
返回类型:Task

CommitTransactionAsync()

提交此会话的ACID 事务。如果会话没有ACID 事务或ACID 事务已结束,则会引发异常。要学习;了解有关此方法的更多信息,请参阅服务器手册中的 commitTransaction()

页面。参数:CancellationToken
返回类型:Task

WithTransactionAsync()

在此会话上启动事务并运行给定的回调。要了解有关此方法的更多信息,请参阅服务器手册中的 withTransaction() 页面

重要提示:在 WithTransactionAsync()使用的回调函数中捕获异常时,必须在退出 try-catch区块之前重新抛出异常。否则可能会导致无限循环。 有关如何处理这种情况下的异常的更多详细信息,请参阅《服务器》手册中的“事务”,并从语言下拉列表中选择 C#以查看示例。


参数:Func <IClientSessionHandle, CancellationToken, Task<TResult>>TransactionOptionsCancellationToken
返回类型:Task <TResult>

提示

配置事务

您可以通过将 TransactionOptions 类的实例传递给 StartTransaction()WithTransaction() 方法来自定义单个事务的行为。您在此处设立的选项会覆盖您在 ClientSessionOptions对象上设立的默认ACID 事务选项。

此示例展示了如何通过以下步骤创建会话、创建事务以及将文档插入到事务中的多个集合中:

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

  2. 创建 TransactionOptions对象以配置ACID 事务。

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

  4. 将文档插入 booksfilms 集合。

  5. 使用 CommitTransaction() 方法提交事务。

var books = database.GetCollection<Book>("books");
var films = database.GetCollection<Film>("films");
// Begins transaction
using (var session = mongoClient.StartSession())
{
// Configures transaction options
var transactionOptions = new TransactionOptions(
readConcern: ReadConcern.Majority,
writeConcern: WriteConcern.WMajority
);
session.StartTransaction(transactionOptions);
try
{
// Creates sample data
var book = new Book
{
Title = "Beloved",
Author = "Toni Morrison",
InStock = true
};
var film = new Film
{
Title = "Star Wars",
Director = "George Lucas",
InStock = true
};
// Inserts sample data
books.InsertOne(session, book);
films.InsertOne(session, film);
// Commits our transaction
session.CommitTransaction();
}
catch (Exception e)
{
Console.WriteLine("Error writing to MongoDB: " + e.Message);
return;
}
// Prints a success message if no error thrown
Console.WriteLine("Successfully committed transaction!");
}
Successfully committed transaction!

注意

不支持并行操作

.NET/ C#驱动程序不支持在单个ACID 事务中运行并行操作。

如果您使用的是MongoDB Server v8.0 或更高版本,则可以使用 BulkWrite()BulkWriteAsync() 方法在单个ACID 事务中对多个命名空间执行写入操作。 有关更多信息,请参阅批量写入操作。

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

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