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

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

The Callback API:

The Core API:

回调 API 包含以下逻辑:

Starting in MongoDB 6.2, the server does not retry the transaction if it receives a TransactionTooLargeForCache error.

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

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

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

事务中的单独写入操作不可重试,无论 retryWrites 的值如何。如果操作遇到与标签相关的 "TransientTransactionError" 错误(例如主节点降级时),可以将事务作为一个整体进行重试。

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

  • The core transaction API does not incorporate retry logic for "TransientTransactionError". To handle "TransientTransactionError", applications should explicitly incorporate retry logic for the error. To view an example that incorporates retry logic for transient errors, see Core API Example.

提交操作是可重试写入操作。如果提交操作遇到错误,那么无论 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 命令修改错误阈值。

The following mongosh methods are available for transactions:

注意

The mongosh example omits retry logic and robust error handling for simplicity's sake. For a more practical example of incorporating transactions in applications, see Transaction Error Handling instead.

// 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();