根本原因是客户端context超时与服务端transactionLifetimeLimitSeconds、heartbeatFrequencyMS未协同适配;需将服务端transactionLifetimeLimitSeconds设为180秒、heartbeatFrequencyMS设为2000ms,并在Go中用≤140秒的context.WithTimeout覆盖整个事务生命周期。

事务提交卡在 commitTransaction 阶段并报 context deadline exceeded 或 Transaction is not in progress,不是代码写错了,而是上下文超时和 MongoDB 服务端参数没对齐——尤其在跨 AZ、VPC 对等连接或公网直连场景下,必须同时调两端。
Go 里 context.WithTimeout 不够用,得配 service 端参数
只在 Go 侧用 context.WithTimeout(ctx, 30*time.Second) 是治标不治本。MongoDB 服务端有硬性限制:transactionLifetimeLimitSeconds 默认 60 秒,但它是从 startTransaction 开始计时,不包含网络传输延迟。如果 RTT 达到 80ms,一次 commit 往返就可能吃掉 200ms,100 次操作叠加抖动后很容易突破阈值。
- 必须同步调大服务端
transactionLifetimeLimitSeconds:副本集配置中设为180(单位秒),命令是rs.reconfig({...}, {force: true}) - Go 客户端 context 超时建议设为 ≤ 服务端值的 80%,比如服务端 180 秒,Go 侧用
context.WithTimeout(ctx, 140*time.Second) - 别依赖
client.Timeout()全局设置——它不作用于事务 commit 阶段,只影响单次 CRUD;事务生命周期由 context 和服务端共同约束
心跳失准导致事务上下文丢失
事务过程中客户端和服务端靠心跳维持连接状态。默认 heartbeatFrequencyMS=10000(10 秒)在高延迟网络下形同虚设:节点已断连 20 秒,驱动还在等下次心跳,结果 commitTransaction 发出去时连接早被中间件(SLB/Nginx)断开,上下文失效,后续操作全报 Transaction is not in progress。
- 根据实测 RTT 设置
heartbeatFrequencyMS:RTT 50–100ms → 设为2000;RTT > 200ms → 不低于5000 -
electionTimeoutMillis必须 ≥heartbeatFrequencyMS × 5,否则副本集频繁误判宕机;例如heartbeatFrequencyMS=2000时,electionTimeoutMillis至少设为10000 - 这两个参数不能只改客户端配置——
heartbeatFrequencyMS是驱动读取的副本集配置项,要通过rs.reconfig()更新;electionTimeoutMillis是 mongod 启动参数或 rs.conf() 里的 settings,需重启或 reconfig 生效
事务外层 context 必须覆盖整个生命周期
常见错误是只给 InsertOne 或 UpdateOne 单个操作设 context,而没把 Session.StartTransaction() 到 session.CommitTransaction() 全包进去。一旦中间某个操作超时,session 内部状态就乱了,CommitTransaction 会直接失败。
- 所有事务内操作共用同一个 context,且该 context 必须在
session.StartTransaction()前创建 - 不要在事务块里嵌套新 context:比如
FindOne(ctx, ...)用了另一个WithTimeout,容易提前 cancel 整个 session - 显式 defer
session.EndSession(),但注意它不自动 rollback;rollback 要靠session.AbortTransaction()显式触发,且同样受 context 控制
最易被忽略的是:事务上下文超时不是纯 Go 层问题,而是客户端驱动、网络链路、MongoDB 副本集配置三者耦合的结果。单独调任何一端都解决不了根本问题,必须按 RTT 测量值联动调整 heartbeatFrequencyMS、transactionLifetimeLimitSeconds 和 Go 的 context 超时三者。



















