事务性能优化指南
概述
本文档说明调优事务吞吐与缓存一致性时真正需要关注的行为:
- 只读事务统计 - 未执行 monSQLize 写 helper 的事务会在
getTransactionStats()中单独计数。 - 进程内缓存失效屏障 - 显式配置缓存失效的事务写入会记录 intent,只在事务成功 commit 后 flush。
适用场景
优化1: 只读优化
工作原理
使用方式
只读事务无需额外代码。事务没有执行 monSQLize 写 helper 时,会被统计为只读事务。
优化2: 缓存失效屏障
工作原理
事务通过 monSQLize helper 写入且显式配置了缓存失效时,runtime 会记录读缓存失效 intent。MongoDB commit 成功后再 flush 已记录的失效并释放进程内缓存锁;abort 不会 flush。
使用方式
需要事务写入清理读缓存时,同时传入 session: tx.session 与 cache.invalidate 或 autoInvalidate: true。
边界
使用建议
1. 缩小事务写入范围
推荐:
- 让事务尽量短。
- 只给必须进入事务的操作传入
session: tx.session。 - 使用有索引的目标过滤条件,让 MongoDB 更容易处理写冲突。
避免:
- 在事务回调里执行长耗时网络调用。
- 未测量前把大量批量更新塞进一个事务。
- 把 monSQLize 缓存锁当成跨进程业务锁。
2. 充分利用只读优化
✅ 推荐场景:
- 报表查询
- 数据分析
- 只读副本
最佳实践:
3. 监控事务统计
4. 配置调优
监控指标
关键指标
监控脚本示例
常见问题
Q1: 缓存屏障会增加内存使用吗?
A: 屏障和缓存锁元数据是进程内、短生命周期的。若有大量并发长事务,应同时观察 activeTransactions 与进程 RSS。
Q2: 如何观察事务行为?
A: 使用单个事务统计和聚合统计:
Q3: 只读优化会影响数据一致性吗?
A: 不会。
- 只读事务仍然在事务隔离级别下执行
- 只是不失效缓存,不影响数据准确性
- 事务内读取的数据仍然是一致的快照
Q4: 单次事务可以禁用缓存锁吗?
A: 可以。向事务 options 传入 enableCacheLock: false 后,会保留 MongoDB driver 事务语义,但不启用进程内缓存锁。缓存失效仍遵循文档中的 best-effort 边界。
总结
应该观测什么
建议
- 保持事务 callback 短小且幂等。
- 定期查看
getTransactionStats()。 - 基于观测结果调 timeout、retry 与 cache-lock 配置。