MongoDB 6.0跨分片长事务天生低效,需设transactionLifetimeLimitSeconds为30~45秒、禁用阻塞I/O、调优WiredTiger缓存与驱逐参数、拆分$lookup查询,并聚焦单分片锁竞争与缓存压力优化。

跨分片长事务在 MongoDB 6.0 中无法“优化执行效率”,只能限制其发生、加速其失败或回滚——它天生不适合高频、长耗时场景。
transactionLifetimeLimitSeconds 必须设为 30~45 秒,且不能动态改
该参数是 mongos 端的事务超时检查阈值,默认 30 秒(6.0 起从 60 秒下调),但注意:
– 它不是“到点自动回滚”,而是下一次 commitTransaction 或 abortTransaction 时才触发 TransactionTooOld 错误;
– 必须在所有 mongos 实例的配置文件中预设 sharding.transactionLifetimeLimitSeconds: 30,运行时调用 db.adminCommand({ setParameter: 1, transactionLifetimeLimitSeconds: 15 }) 无效;
– 设低于 10 秒会频繁报错,高于 60 秒会让慢事务更难定位,实测业务平均事务耗时 22 秒,设 45 最稳妥;
– 单分片直连事务不受此限,但生产环境严禁直连 shard 执行事务。
事务内禁止任何阻塞 I/O 和跨服务调用
这是长事务最常见源头,且 6.0 完全不缓解:
– HTTP 请求(如支付回调、风控校验)、RPC、数据库外查、文件读写,一律前置完成并缓存结果;
– 事务块必须包在 try/catch/finally 中,finally 里无条件调用 session.abortTransaction()(即使已 commit 也安全);
– 批量操作必须拆分:单事务最多 100~500 条写入,配合 maxTimeMS: 5000 防止单条命令卡死;
– 不要依赖“事务内重试逻辑”,WiredTiger 的 WriteConflict 在跨分片场景下恢复成本极高。
wiredTigerCacheSizeGB 和 eviction 参数必须协同调优
事务修改全部暂存在 WiredTiger 内存页中,缓存不足直接引发 WT_ROLLBACK 或 WT_DEADLOCK:
– 64GB 物理内存服务器,wiredTigerCacheSizeGB: 42 比默认 32GB 提升约 22% TPS;
– 同步调整 eviction_target: 75(默认 80)和 eviction_trigger: 85(默认 90),过高会提前刷盘加重 I/O,过低则堆积脏页;
– 验证是否健康:观察 db.serverStatus().wiredTiger.cache["pages evicted by application threads"] 是否持续增长;
– 切勿只调 cacheSizeGB 而忽略 eviction,二者失配比单设更危险。
跨分片 $lookup 会被硬拦截,别试图绕过
哪怕目标集合未分片,只要事务内用了 $lookup 且集群启用了分片,就会报 TransactionNotSupportedOnShardedCollection:
– 这不是 bug,是 6.0 明确保留的设计限制,优化聚焦协调器通信,没动聚合引擎的事务校验逻辑;
– 正确做法是拆成两步:先查主表 ID 列表(带 hint 确保走索引),再用这些 ID 批量 $in 查询副表;
– 若副表也分片,确保 $in 查询的字段是它的分片键,否则仍会广播扫描;
– 不要用 $facet 或子查询模拟 $lookup,同样被拒绝。
真正影响跨分片事务响应的,从来不是“能不能提交”,而是每个分片上单节点的锁竞争、oplog 写入节奏、以及 WiredTiger 缓存是否在事务高峰期瞬间打满——这些点一旦出问题,TransactionTooOld 就只是最先暴露的症状。

















