MongoDB 事务功能文档
版本: v1.0.0
更新日期: 2025-11-19
📚 目录
概述
monSQLize 提供完整的 MongoDB 事务支持,确保数据的原子性、一致性、隔离性和持久性(ACID)。
核心特性
- ✅ 自动事务管理(withTransaction - 推荐)
- ✅ 手动事务管理(startSession - 高级用法)
- ✅ 智能缓存策略(事务内可选缓存,事务外正常缓存)
- ✅ 缓存锁机制(防止脏数据)
- ✅ 自动重试(瞬态错误自动重试)
- ✅ 超时处理(自动中断长事务)
- ✅ 监控指标(执行时长、成功率等)
- ✅ 读关注/读偏好/因果一致性
前置要求
- ✅ MongoDB 4.0+ 副本集或分片集群
- ✅ Node.js 14+
- ✅ monSQLize v1.0.0+
快速开始
1. 初始化与配置
2. 使用自动事务(推荐⭐)
最简单的方式,自动管理提交、回滚和重试:
3. 使用手动事务(高级用法)
需要精细控制事务生命周期时使用:
配置选项
全局配置(构造函数)
单次事务配置
API 参考
msq.withTransaction(callback, options)
自动管理事务(推荐)。
参数:
callback(tx): 事务回调函数tx.session: MongoDB session 对象tx.id: 事务唯一标识tx.state: 事务状态('pending' | 'active' | 'committed' | 'aborted')
options: 事务选项(可选)
返回: Promise
示例:
msq.startSession(options)
创建手动事务会话。
参数:
options: 事务选项(同 withTransaction)
返回: Promise
Transaction 实例方法:
start(): 开始事务commit(): 提交事务abort(): 回滚事务end(): 释放资源
示例:
缓存策略
⭐ 默认策略:事务内不缓存(推荐)
设计理念: 事务追求数据一致性,缓存追求性能。默认情况下,事务内操作不使用缓存,确保数据准确性。
可选策略:事务内启用缓存(性能优化)
使用场景: 事务内多次查询相同数据,且可以接受事务开始时的快照数据。
缓存锁机制(自动)
作用: 防止事务执行期间,外部操作写入脏数据到缓存。
缓存策略对比
最佳实践
1. 幂等性设计 ⭐
重要: 事务回调必须幂等,因为可能自动重试。
2. 超时时间设置
3. 错误处理
4. 性能优化
5. 监控与日志
常见问题
Q1: 为什么事务内查询没有使用缓存?
A: 这是设计的默认行为。原因:
- 数据一致性优先 - 事务追求准确性,缓存可能有延迟
- 避免脏读 - 事务内应该读取最新数据
- 简化使用 - 用户不需要考虑缓存问题
如果需要性能优化,可以显式启用 cache 选项。
Q2: 什么时候使用手动事务?
A: 大多数情况使用 withTransaction(自动)。以下情况考虑手动:
- 需要在事务开始前做复杂判断
- 需要在 commit 前做额外验证
- 需要细粒度控制事务生命周期
Q3: 事务失败如何调试?
A: 检查以下几点:
- MongoDB 是副本集吗? - 单节点不支持事务
- 连接字符串正确吗? - 需要
?replicaSet=rs0 - 超时时间合理吗? - 默认30秒
- 回调是否幂等? - 可能重试多次
Q4: 缓存锁会影响性能吗?
A: 影响很小。原因:
- 锁仅在事务执行期间生效(通常很短)
- 锁是内存级别的(不涉及 I/O)
- 锁的检查非常快(O(1) 哈希查找)
Q5: 事务内可以操作多个数据库吗?
A: 可以,但有限制:
- ✅ 同一个 MongoDB 集群内的多个数据库
- ❌ 跨 MongoDB 集群(不支持)
Q6: 并发事务会死锁吗?
A: MongoDB 会自动检测并抛出 WriteConflict 错误。monSQLize 会自动重试(如果启用了 enableRetry)。
性能优化
1. 减少事务内操作
2. 批量操作
3. 合理使用索引
4. 监控事务性能
相关文档
- MongoDB 事务官方文档
- [设计文档]
- 示例代码
文档版本: v1.0.0
最后更新: 2025-11-19
贡献者: monSQLize 团队