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

使用驱动程序API处理应用程序中的事务

Callback API:

核心 API:

回调 API 包含以下逻辑:

从 MongoDB 6.2 开始,服务器在收到 TransactionTooLargeForCache 错误时不会重试事务。

核心事务 API 不包含标记为以下错误的重试逻辑:

以下示例包含在出现暂时性错误时重试事务的逻辑,以及在出现未知提交错误时重试提交的逻辑:

无论是何种数据库系统,无论是 MongoDB 还是关系型数据库,应用程序都应采取相应措施来处理事务提交期间的错误,并包含事务的重试逻辑。

ACID 事务中的各个写入操作不可重试,无论retryWrites 的值如何。如果操作遇到与标签"TransientTransactionError" 相关的错误,例如当主节点 (primary node in the replica set)节点降级时,则可以重试整个ACID 事务。

  • 回调 API 包含 "TransientTransactionError" 的重试逻辑。

  • 核心事务 API 不包含 "TransientTransactionError" 的重试逻辑。要处理 "TransientTransactionError",应用程序应显式包含错误的重试逻辑。要查看包含瞬时错误重试逻辑的示例,请参阅 Core API 示例。

提交操作是可重试写入操作。如果提交操作遇到错误,那么无论 retryWrites 的值如何,MongoDB 驱动程序都会重试提交。

如果提交操作遇到标记为 "UnknownTransactionCommitResult" 的错误,则可以重试提交。

  • 回调 API 包含 "UnknownTransactionCommitResult" 的重试逻辑。

  • 核心事务 API 不包含 "UnknownTransactionCommitResult" 的重试逻辑。要处理 "UnknownTransactionCommitResult",应用程序应显式包含错误的重试逻辑。要查看包含未知提交错误的重试逻辑示例,请参阅 Core API 示例。

6.2版本新增。

从 MongoDB 6.2 开始,服务器在收到 TransactionTooLargeForCache 错误后不会重试事务。此错误意味着缓存过小,重试可能会失败。

transactionTooLargeForCacheThreshold 阈值的默认值为 0.75。当事务使用超过 75% 的缓存时,服务器会返回 TransactionTooLargeForCache 而不是重试事务。

在 MongoDB 的早期版本中,服务器会返回 TemporarilyUnavailable 或 WriteConflict,而不是 TransactionTooLargeForCache。

使用 setParameter 命令修改错误阈值。

以下 mongosh 方法适用于事务:

注意

为简单起见,mongosh 示例省略了重试逻辑和强大的错误处理功能。有关在应用程序中合并事务的更实际示例,请改为参阅事务错误处理。

// Create collections:
db.getSiblingDB("mydb1").foo.insertOne(
{abc: 0},
{ writeConcern: { w: "majority", wtimeout: 2000 } }
)
db.getSiblingDB("mydb2").bar.insertOne(
{xyz: 0},
{ writeConcern: { w: "majority", wtimeout: 2000 } }
)
// Start a session.
session = db.getMongo().startSession( { readPreference: { mode: "primary" } } );
coll1 = session.getDatabase("mydb1").foo;
coll2 = session.getDatabase("mydb2").bar;
// Start a transaction
session.startTransaction( { readConcern: { level: "local" }, writeConcern: { w: "majority" } } );
// Operations inside the transaction
try {
coll1.insertOne( { abc: 1 } );
coll2.insertOne( { xyz: 999 } );
} catch (error) {
// Abort transaction on error
session.abortTransaction();
throw error;
}
// Commit the transaction using write concern set at transaction start
session.commitTransaction();
session.endSession();