mongodb protocol_error ai_generated true

MongoServerError: 会话 0x1234 上的事务编号 1 不是预期的事务编号(预期 2)

MongoServerError: Transaction number 1 on session 0x1234 is not the expected transaction number (expected 2)

ID: mongodb/transaction-number-mismatch

其他格式: JSON · Markdown 中文 · English
88%修复率
84%置信度
1证据数
2024-02-28首次发现

版本兼容性

版本状态引入弃用备注
MongoDB 4.2 active
MongoDB 5.0 active
MongoDB 6.0 active
MongoDB 7.0 active

根因分析

客户端尝试使用过时的事务编号提交或中止事务,可能是由于重试逻辑错误,同一会话被重用而未递增事务编号,或会话被意外地在并发事务间共享。

English

A client attempted to commit or abort a transaction with a stale transaction number, likely due to a retry logic bug where the same session is reused without incrementing the transaction number, or a session is accidentally shared across concurrent transactions.

generic

官方文档

https://www.mongodb.com/docs/manual/core/transactions/

解决方案

  1. 确保每个事务使用新会话或显式递增事务编号。在 Node.js 驱动中:在每次尝试的循环中使用 `session.startTransaction()` 和 `session.commitTransaction()` 创建新会话。示例:`const session = client.startSession(); session.startTransaction(); try { ... await session.commitTransaction(); } catch { await session.abortTransaction(); } finally { session.endSession(); }`
  2. 对于重试逻辑,每次重试尝试使用新会话,而不是重用同一会话。在 Python 中:在重试循环内使用 `with client.start_session() as session: session.start_transaction(); ...`。
  3. 检查异步代码中的意外会话共享(例如,将同一会话对象传递给多个并发协程)。如果驱动程序支持,使用 `session.advanceTransactionNumber()`,或强制每个会话按顺序处理事务。

无效尝试

常见但无效的做法:

  1. 90% 失败

    The underlying session management bug in the code remains; the error will recur on the next transaction.

  2. 85% 失败

    Killing the session only frees server resources; the client code still holds a stale session reference and will create a new session with the same problem.

  3. 95% 失败

    The error is about transaction number sequencing, not timeout; changing timeouts has no effect.