MongoServerError: 会话 0x1234 上的事务编号 1 不是预期的事务编号(预期 2)
MongoServerError: Transaction number 1 on session 0x1234 is not the expected transaction number (expected 2)
ID: mongodb/transaction-number-mismatch
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| 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.
官方文档
https://www.mongodb.com/docs/manual/core/transactions/解决方案
-
确保每个事务使用新会话或显式递增事务编号。在 Node.js 驱动中:在每次尝试的循环中使用 `session.startTransaction()` 和 `session.commitTransaction()` 创建新会话。示例:`const session = client.startSession(); session.startTransaction(); try { ... await session.commitTransaction(); } catch { await session.abortTransaction(); } finally { session.endSession(); }` -
对于重试逻辑,每次重试尝试使用新会话,而不是重用同一会话。在 Python 中:在重试循环内使用 `with client.start_session() as session: session.start_transaction(); ...`。
-
检查异步代码中的意外会话共享(例如,将同一会话对象传递给多个并发协程)。如果驱动程序支持,使用 `session.advanceTransactionNumber()`,或强制每个会话按顺序处理事务。
无效尝试
常见但无效的做法:
-
90% 失败
The underlying session management bug in the code remains; the error will recur on the next transaction.
-
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.
-
95% 失败
The error is about transaction number sequencing, not timeout; changing timeouts has no effect.