monsqlize 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CHANGELOG.md +92 -2419
  2. package/README.md +630 -1070
  3. package/index.d.ts +252 -15
  4. package/lib/cache.js +8 -8
  5. package/lib/common/validation.js +64 -1
  6. package/lib/connect.js +3 -3
  7. package/lib/errors.js +10 -0
  8. package/lib/index.js +118 -9
  9. package/lib/infrastructure/ssh-tunnel-ssh2.js +211 -0
  10. package/lib/infrastructure/ssh-tunnel.js +40 -0
  11. package/lib/infrastructure/uri-parser.js +35 -0
  12. package/lib/lock/Lock.js +66 -0
  13. package/lib/lock/errors.js +27 -0
  14. package/lib/lock/index.js +12 -0
  15. package/lib/logger.js +1 -1
  16. package/lib/model/examples/test.js +4 -4
  17. package/lib/mongodb/common/accessor-helpers.js +17 -3
  18. package/lib/mongodb/connect.js +68 -13
  19. package/lib/mongodb/index.js +140 -7
  20. package/lib/mongodb/management/collection-ops.js +4 -4
  21. package/lib/mongodb/management/index-ops.js +18 -18
  22. package/lib/mongodb/management/validation-ops.js +3 -3
  23. package/lib/mongodb/queries/aggregate.js +14 -5
  24. package/lib/mongodb/queries/chain.js +52 -45
  25. package/lib/mongodb/queries/count.js +16 -6
  26. package/lib/mongodb/queries/distinct.js +15 -6
  27. package/lib/mongodb/queries/find-and-count.js +22 -13
  28. package/lib/mongodb/queries/find-by-ids.js +5 -5
  29. package/lib/mongodb/queries/find-one-by-id.js +1 -1
  30. package/lib/mongodb/queries/find-one.js +12 -3
  31. package/lib/mongodb/queries/find-page.js +12 -0
  32. package/lib/mongodb/queries/find.js +15 -6
  33. package/lib/mongodb/queries/index.js +1 -0
  34. package/lib/mongodb/queries/watch.js +537 -0
  35. package/lib/mongodb/writes/delete-many.js +20 -11
  36. package/lib/mongodb/writes/delete-one.js +18 -9
  37. package/lib/mongodb/writes/find-one-and-delete.js +19 -10
  38. package/lib/mongodb/writes/find-one-and-replace.js +36 -20
  39. package/lib/mongodb/writes/find-one-and-update.js +36 -20
  40. package/lib/mongodb/writes/increment-one.js +16 -7
  41. package/lib/mongodb/writes/index.js +13 -13
  42. package/lib/mongodb/writes/insert-batch.js +46 -37
  43. package/lib/mongodb/writes/insert-many.js +22 -13
  44. package/lib/mongodb/writes/insert-one.js +18 -9
  45. package/lib/mongodb/writes/replace-one.js +33 -17
  46. package/lib/mongodb/writes/result-handler.js +14 -14
  47. package/lib/mongodb/writes/update-many.js +34 -18
  48. package/lib/mongodb/writes/update-one.js +33 -17
  49. package/lib/mongodb/writes/upsert-one.js +25 -9
  50. package/lib/operators.js +1 -1
  51. package/lib/redis-cache-adapter.js +3 -3
  52. package/lib/slow-query-log/base-storage.js +69 -0
  53. package/lib/slow-query-log/batch-queue.js +96 -0
  54. package/lib/slow-query-log/config-manager.js +195 -0
  55. package/lib/slow-query-log/index.js +237 -0
  56. package/lib/slow-query-log/mongodb-storage.js +323 -0
  57. package/lib/slow-query-log/query-hash.js +38 -0
  58. package/lib/transaction/DistributedCacheLockManager.js +240 -5
  59. package/lib/transaction/Transaction.js +1 -1
  60. package/lib/utils/objectid-converter.js +566 -0
  61. package/package.json +11 -5
package/CHANGELOG.md CHANGED
@@ -1,2474 +1,147 @@
1
- # 变更日志
1
+ # 变更日志 (CHANGELOG)
2
2
 
3
- 所有显著变更将记录在此文件,遵循 Keep a Changelog 与语义化版本(SemVer)。
4
-
5
- ## [1.0.0] - 2025-12-02
6
-
7
- ### 🎉 正式发布 v1.0.0
8
-
9
- **里程碑**: 生产就绪版本,所有核心功能完整实现并经过充分测试
10
-
11
- ### 核心功能
12
-
13
- **✅ CRUD 操作(100% 完成)**
14
- - Create: insertOne, insertMany, insertBatch(高性能批处理)
15
- - Read: find, findOne, findPage(游标分页), aggregate, count, distinct
16
- - Update: updateOne, updateMany, replaceOne, findOneAndUpdate, findOneAndReplace
17
- - Delete: deleteOne, deleteMany, findOneAndDelete
18
-
19
- **✅ 索引管理(100% 完成)**
20
- - createIndex, createIndexes, listIndexes, dropIndex, dropIndexes
21
- - 支持所有索引类型(单字段、复合、唯一、TTL、文本、地理空间等)
22
-
23
- **✅ 事务支持(100% 完成)**
24
- - withTransaction(自动管理)
25
- - startTransaction(手动管理)
26
- - 缓存锁机制(防止脏读)
27
- - 只读优化(-30% DB访问)
28
- - 文档级别锁(16倍并发提升)
29
- - 重试、超时、监控
30
-
31
- **✅ 便利方法(100% 完成)**
32
- - findOneById - 减少 80% 单文档查询代码
33
- - findByIds - 批量查询,1次 DB 调用
34
- - upsertOne - 简化 upsert 操作
35
- - incrementOne - 原子递增/递减
36
- - findAndCount - 同时返回数据和总数(并行执行)
37
-
38
- **✅ 分布式支持(100% 完成)**
39
- - 多实例缓存一致性(Redis Pub/Sub 广播)
40
- - 分布式事务锁(跨实例隔离)
41
- - 1-5ms 实时广播延迟
42
-
43
- **✅ Admin/Management 功能(100% 完成)**
44
- - 运维监控: ping, buildInfo, serverStatus, stats
45
- - 数据库管理: listDatabases, dropDatabase, listCollections, runCommand
46
- - Schema 验证: setValidator, setValidationLevel, setValidationAction, getValidator
47
- - 集合管理: stats, renameCollection, collMod, convertToCapped
48
-
49
- ### 性能优化
50
-
51
- - ✨ **智能缓存系统**: TTL/LRU/自动失效/多层缓存
52
- - ✨ **高性能批处理**: insertBatch 10-50x 性能提升
53
- - ✨ **深度分页**: 游标分页支持千万级数据
54
- - ✨ **并发优化**: 文档级别锁,16倍并发提升
55
-
56
- ### 企业级特性
57
-
58
- - 🔒 **完整的事务支持**: 自动管理、手动管理、分布式锁
59
- - 🌐 **分布式部署**: 多实例缓存一致性
60
- - 🛠️ **运维监控**: 健康检查、性能监控、慢查询日志
61
- - 🔐 **安全机制**: dropDatabase 三重保护、审计日志
62
-
63
- ### 质量保证
64
-
65
- - ✅ **测试覆盖率**: 77%+
66
- - ✅ **测试用例**: 1000+ 个测试用例,100% 通过
67
- - ✅ **文档完整性**: 100% API 文档覆盖
68
- - ✅ **示例代码**: 50+ 可运行示例
69
-
70
- ### 兼容性
71
-
72
- - ✅ MongoDB Node.js Driver 6.x(完全测试并支持)
73
- - ✅ Node.js 14.x+(推荐 16.x, 18.x, 20.x)
74
-
75
- ### Breaking Changes
76
-
77
- 无破坏性变更(从 v0.3.0 平滑升级)
3
+ > **说明**: 版本摘要,详细需求见 [STATUS.md](STATUS.md)
4
+ > **最后更新**: 2025-12-29
78
5
 
79
6
  ---
80
7
 
81
- ## [0.3.0] - 2025-12-02
82
-
83
- ### Added
84
-
85
- #### 🛠️ Admin/Management 功能 - v0.3.0(2025-12-02 - 完成)
86
-
87
- **运维监控(4个方法)** ✅
88
- - ✨ `ping()` - 检测数据库连接是否正常
89
- - ✨ `buildInfo()` - 获取 MongoDB 版本信息
90
- - ✨ `serverStatus()` - 获取服务器状态(连接数、内存、操作统计)
91
- - ✨ `stats()` - 获取数据库统计信息(大小、集合数、索引数)
92
-
93
- **数据库操作(4个方法)** ✅
94
- - ✨ `listDatabases()` - 列出所有数据库
95
- - ✨ `dropDatabase()` - 删除数据库(带完整安全机制)
96
- - ✨ `listCollections()` - 列出所有集合
97
- - ✨ `runCommand()` - 执行任意 MongoDB 命令
98
-
99
- **Schema 验证(4个方法)** ✅
100
- - ✨ `setValidator()` - 设置集合 Schema 验证规则(JSON Schema / 查询表达式)
101
- - ✨ `setValidationLevel()` - 设置验证级别(off/strict/moderate)
102
- - ✨ `setValidationAction()` - 设置验证行为(error/warn)
103
- - ✨ `getValidator()` - 获取当前验证配置
8
+ ## 版本概览
104
9
 
105
- **集合管理(7个方法)**
106
- - ✨ `collection.stats()` - 获取集合统计信息
107
- - `renameCollection()` - 重命名集合
108
- - `collMod()` - 修改集合属性
109
- - ✨ `convertToCapped()` - 转换为固定大小集合
110
- - ✨ `createCollection()` - 支持创建 capped 和 time-series 集合
10
+ | 版本 | 日期 | 变更摘要 | 详细 |
11
+ |------|------|---------|------|
12
+ | [v1.0.1](STATUS.md#v101) | 2025-12-29 | 稳定版本,生产就绪 | [查看](STATUS.md#v101) |
13
+ | [v1.0.0](STATUS.md#v100) | 2025-12-03 | 正式发布,生产就绪,已发布到 npm | [查看](STATUS.md#v100) |
111
14
 
112
- **安全机制** ✅
113
- - 🔒 dropDatabase 三重保护:
114
- - 强制确认(confirm: true)
115
- - 生产环境保护(allowProduction: true)
116
- - 完整审计日志(记录所有删除尝试)
117
-
118
- **核心文件** ✅
119
- - 📦 `lib/mongodb/management/admin-ops.js` - 运维监控方法
120
- - 📦 `lib/mongodb/management/database-ops.js` - 数据库操作方法
121
- - 📦 `lib/mongodb/management/validation-ops.js` - 验证功能方法
122
- - 📦 `lib/mongodb/management/collection-ops.js` - 集合管理方法
123
- - 📦 `lib/mongodb/index.js` - 集成所有管理方法到主类
124
-
125
- **测试** ✅
126
- - ✅ `test/unit/infrastructure/admin.test.js` - 17 个测试用例
127
- - ✅ `test/unit/infrastructure/database.test.js` - 21 个测试用例
128
- - ✅ `test/unit/infrastructure/validation.test.js` - 24 个测试用例
129
- - ✅ `test/unit/infrastructure/collection-mgmt.test.js` - 20 个测试用例
130
- - ✅ **102 个测试用例,100% 通过**
131
- - ✅ 测试覆盖率 > 80%
15
+ ---
132
16
 
133
- **文档** ✅
134
- - 📚 `docs/admin.md` - 运维监控 API 文档(450 行)
135
- - 📚 `docs/database-ops.md` - 数据库操作 API 文档(180 行)
136
- - 📚 `docs/validation.md` - Schema 验证 API 文档(200 行)
137
- - 📚 `docs/collection-mgmt.md` - 集合管理 API 文档(170 行)
138
- - 📚 `examples/admin.examples.js` - 完整示例代码(16 个场景)
139
- - 📚 **100% 文档覆盖率**
140
17
 
141
- **实现统计**
142
- - ✅ 18 个新方法全部实现
143
- - ✅ 新增代码约 4,100 行
144
- - ✅ 工作效率提升 2.7 倍
145
- - ✅ 提前 2 个版本完成所有功能
18
+ ## 🆕 v1.0.1 变更详情(2025-12-29)
146
19
 
147
- ### Fixed
148
- - 🐛 修复 `createValidationError()` 不支持自定义错误消息的问题
149
- - 🐛 修复 `collection.stats()` 递归调用导致栈溢出的问题
150
- - 🐛 修复 `dropDatabase()` 错误码不正确的问题
151
- - 🐛 修复测试中 admin 数据库删除失败的问题
20
+ ### 版本说明
152
21
 
153
- ### Changed
154
- - ♻️ `errors.js` - 增强 `createValidationError()` 支持自定义消息
155
- - ♻️ `collection-ops.js` - 使用 MongoDB 命令代替递归调用
156
- - ♻️ `database-ops.js` - 使用正确的方式删除指定数据库
22
+ - 稳定版本,生产就绪
23
+ - 包含完整的 CRUD 功能
24
+ - 多级缓存系统
25
+ - 事务支持
26
+ - 分布式部署支持
27
+ - Change Streams 实时监听
28
+ - 慢查询日志
29
+ - 业务级分布式锁
30
+ - SSH 隧道支持
157
31
 
158
32
  ---
159
33
 
160
- ## [未发布]
161
-
162
- ### Added
34
+ ## 🆕 v1.0.0 变更详情(2025-12-03)
163
35
 
164
- #### 🌐 分布式部署支持 - v2.2.0(2025-11-25 - 完成)
36
+ ### 版本说明
165
37
 
166
- **分布式缓存失效**
167
- - ✨ 基于 Redis Pub/Sub 实现跨实例缓存失效广播
168
- - 自动订阅失效消息并更新本地缓存
169
- - ✨ 支持通配符模式匹配(如 `user:*`)
170
- - ✨ 实例ID隔离,避免自我触发
171
- - ✨ 1-5ms 延迟的实时广播
172
- - 🔧 **关键修复**: 添加 `setPublish()` 方法动态注入广播回调,确保分布式失效正常工作
38
+ - 正式版发布,生产就绪
39
+ - 企业级质量标准(96/100 A+)
40
+ - 已发布到 npm
173
41
 
174
- **分布式事务锁** ✅
175
- - 🔒 基于 Redis 实现跨实例的事务缓存锁
176
- - 🔒 使用 SET NX EX 原子操作获取锁
177
- - 🔒 支持锁的自动过期(默认5分钟)
178
- - 🔒 使用 Lua 脚本批量释放锁
179
- - 🔒 防止事务中间状态被其他实例缓存
180
-
181
- **核心文件** ✅
182
- - 📦 `lib/distributed-cache-invalidator.js` - 缓存失效广播器
183
- - 📦 `lib/transaction/DistributedCacheLockManager.js` - 分布式锁管理器
184
- - 📦 `lib/index.js` - 集成分布式组件
185
-
186
- **文档** ✅
187
- - 📚 `docs/distributed-deployment.md` - 完整的部署指南(5种架构方案)
188
- - 📚 `examples/distributed-deployment.examples.js` - 3个可运行示例
189
- - 📚 `docs/INDEX.md` - 更新文档索引
190
- - 📚 `README.md` - 更新功能说明
42
+ ---
191
43
 
192
- **配置支持**
193
- - ⚙️ `cache.distributed.enabled` - 启用分布式缓存失效
194
- - ⚙️ `cache.distributed.redisUrl` - Redis连接URL
195
- - ⚙️ `cache.distributed.channel` - 自定义频道
196
- - ⚙️ `cache.transaction.distributedLock` - 配置分布式事务锁
44
+ ## 变更统计
197
45
 
198
- #### 🚀 事务性能优化 - v2.1.0(2025-11-19 18:30 - 完成)
46
+ | 版本系列 | 版本数 | 主要改进方向 |
47
+ |---------|-------|------------|
48
+ | v1.0.x | 2 | 稳定运行、生产就绪 |
199
49
 
200
- **优化1: 只读优化** ✅
201
- - ✨ 自动识别只读事务
202
- - ✨ 只读事务不失效缓存
203
- - ✨ 减少30% DB访问
204
- - ✨ 追踪只读/写入事务统计
50
+ ---
205
51
 
206
- **优化2: 文档级别锁** ✅
207
- - 🚀 精确锁定涉及的文档(而非整个集合)
208
- - 🚀 10-100倍并发性能提升
209
- - 🚀 支持简单 _id 查询和 $in 查询
210
- - 🚀 无法提取文档键时智能回退到集合级别锁
52
+ ## 维护说明
211
53
 
212
- **统计功能**
213
- - 📊 `TransactionManager.getStats()` - 获取事务统计
214
- - 📊 追踪只读事务占比
215
- - 📊 追踪平均耗时、P95、P99延迟
216
- - 📊 追踪成功率和事务类型分布
54
+ ### 添加新版本的步骤
217
55
 
218
- **文档**
219
- - 📚 `docs/transaction-optimizations.md` - 性能优化指南
220
- - 📚 `examples/transaction-optimizations.examples.js` - 优化示例
56
+ 1. **创建需求文档**(如需要)
57
+ ```bash
58
+ cp plans/TEMPLATE.md plans/req-your-feature.md
59
+ # 填充需求详细信息
60
+ ```
221
61
 
222
- ### Fixed
62
+ 2. **更新 STATUS.md**
63
+ - 在"发布计划"表格添加新版本行
64
+ - 添加版本章节(### vX.Y.Z)
65
+ - 在版本表格添加需求行
66
+ - 链接到 plans/ 文档(如有)
223
67
 
224
- #### 🔧 完成所有写操作的事务集成(2025-11-19 20:00)
68
+ 3. **更新 CHANGELOG.md**
69
+ - 在"版本概览"表格最上方添加新行
70
+ - 格式:`| [vX.Y.Z](STATUS.md#vxyz) | 日期 | 摘要 | [查看](STATUS.md#vxyz) |`
225
71
 
226
- **修复文件**
227
- - 🔧 `lib/mongodb/writes/insert-one.js` - 添加事务缓存锁支持
228
- - 🔧 `lib/mongodb/writes/insert-many.js` - 添加事务缓存锁支持
229
- - 🔧 `lib/mongodb/writes/find-one-and-update.js` - 添加事务缓存锁支持
230
- - 🔧 `lib/mongodb/writes/find-one-and-replace.js` - 添加事务缓存锁支持
231
- - 🔧 `lib/mongodb/writes/find-one-and-delete.js` - 添加事务缓存锁支持
232
- - 🔧 `lib/mongodb/writes/increment-one.js` - 添加事务缓存锁支持
233
- - 🔧 `lib/mongodb/writes/upsert-one.js` - 添加事务缓存锁支持
234
- - 🔧 `lib/mongodb/writes/insert-batch.js` - 通过 insertMany 继承事务支持
72
+ 4. **提交变更**
73
+ ```bash
74
+ git add STATUS.md CHANGELOG.md plans/
75
+ git commit -m "docs: 发布 vX.Y.Z"
76
+ ```
235
77
 
236
- **完整性**
237
- - ✅ 所有写操作都支持事务缓存锁机制
238
- - ✅ 所有写操作都支持文档级别锁优化
239
- - ✅ 所有写操作都传递 metadata 参数
240
- - ✅ 所有文件语法验证通过
78
+ ### 版本号规则
241
79
 
242
- **测试用例**
243
- - 🧪 添加 insertOne 事务测试
244
- - 🧪 添加 insertMany 事务测试
245
- - 🧪 添加 findOneAndUpdate 事务测试
246
- - 🧪 添加 findOneAndReplace 事务测试
247
- - 🧪 添加 findOneAndDelete 事务测试
248
- - 🧪 添加 incrementOne 事务测试
249
- - 🧪 添加 upsertOne 事务测试(插入和更新场景)
250
- - 🧪 添加事务回滚测试
80
+ 遵循[语义化版本](https://semver.org/lang/zh-CN/)(Semantic Versioning):
251
81
 
252
- **代码完成度**: 100%(从65%提升到100%)
253
- **测试覆盖度**: 95%(从70%提升到95%)
254
- - 📚 `test/integration/transaction-optimizations.test.js` - 优化测试
82
+ - **MAJOR** (x.0.0) - 不兼容的 API 变更
83
+ - **MINOR** (0.x.0) - 向后兼容的新增功能
84
+ - **PATCH** (0.0.x) - 向后兼容的问题修复
255
85
 
256
- **修改的文件**:
257
- - `lib/transaction/Transaction.js` - 添加操作类型追踪、文档键提取
258
- - `lib/transaction/TransactionManager.js` - 添加统计功能
259
- - `lib/mongodb/writes/*.js` - 传递 metadata 支持文档级别锁
260
- - ✅ `docs/transaction.md` - 更新全局配置说明
261
- - ✅ `design/transaction-complete-design.md` - 更新设计文档
86
+ 示例:
87
+ - `1.0.0 → 1.0.1` - Bug 修复
88
+ - `1.0.0 → 1.1.0` - 新功能
89
+ - `1.0.0 → 2.0.0` - 破坏性变更
262
90
 
263
91
  ---
264
92
 
265
- #### 🎉 事务功能实现 - 完整版(2025-11-19)
93
+ ## 快速导航
266
94
 
267
- **更新**: 2025-11-19 - 实现事务缓存锁机制 + 写操作集成,功能完整 ✅
95
+ ### 当前版本
268
96
 
269
- **核心功能**
97
+ - **v1.0.1**: [查看详情](STATUS.md#v101)
98
+ - **v1.0.0**: [查看详情](STATUS.md#v100)
270
99
 
271
- 1. **Transaction 类** - 事务生命周期管理
272
- - ✅ `start()` - 开始事务
273
- - ✅ `commit()` - 提交事务(释放缓存锁)
274
- - ✅ `abort()` - 回滚事务(释放缓存锁)
275
- - ✅ `recordInvalidation(pattern)` - 记录缓存失效(写时失效 + 添加锁)
276
- - ✅ 超时自动中止
277
- - ✅ 状态管理(pending/active/committed/aborted)
278
-
279
- 2. **TransactionManager 类** - 事务管理器
280
- - ✅ `startSession(options)` - 手动管理事务
281
- - ✅ `withTransaction(callback, options)` - 自动管理事务(推荐)
282
- - ✅ 自动重试瞬态错误(TransientTransactionError)
283
- - ✅ 指数退避重试策略
284
- - ✅ 活跃事务追踪
285
-
286
- 3. **CacheLockManager 类** - 缓存锁机制
287
- - ✅ `addLock(key, session)` - 添加缓存锁
288
- - ✅ `isLocked(key)` - 检查是否被锁定
289
- - ✅ `releaseLocks(session)` - 释放会话的所有锁
290
- - ✅ 自动清理过期锁
291
- - ✅ 支持通配符模式
100
+ ---
292
101
 
293
- 4. **写操作事务集成**
294
- - ✅ `update-one.js` - 事务中写时失效缓存 + 添加锁
295
- - ✅ `update-many.js` - 事务中写时失效缓存 + 添加锁
296
- - ✅ `delete-one.js` - 事务中写时失效缓存 + 添加锁
297
- - ✅ `delete-many.js` - 事务中写时失效缓存 + 添加锁
298
- - ✅ `replace-one.js` - 事务中写时失效缓存 + 添加锁
102
+ ## 里程碑版本
299
103
 
300
- 5. **缓存集成**
301
- - ✅ `Cache.setLockManager()` - 设置锁管理器
302
- - ✅ `Cache.getLockManager()` - 获取锁管理器
303
- - ✅ `Cache.set()` - 写入前检查锁(被锁定则跳过)
104
+ ### v1.0.0 - 正式发布 🎉
304
105
 
305
- 6. **主入口 API**
306
- - ✅ `msq.startSession(options)` - 创建事务会话
307
- - ✅ `msq.withTransaction(callback, options)` - 自动管理事务
308
- - ✅ `connect()` - 初始化 TransactionManager
309
- - ✅ `close()` - 清理所有活跃事务
106
+ **发布日期**: 2025-12-03
107
+ **重要性**: ⭐⭐⭐⭐⭐
310
108
 
311
- **缓存失效策略**
109
+ **核心成就**:
110
+ - ✅ 已发布到 npm
111
+ - ✅ 生产就绪
112
+ - ✅ 企业级质量(96/100 A+)
113
+ - ✅ 1000+ 测试用例
114
+ - ✅ 77%+ 测试覆盖率
312
115
 
313
- - **写时无效化(Write-Through Invalidation)**
314
- - 事务中的写操作立即失效缓存
315
- - 防止其他请求读到缓存中的旧数据
116
+ **详细信息**: [查看 STATUS.md](STATUS.md#v100)
316
117
 
317
- - **缓存锁定(Cache Lock)**
318
- - 写操作后添加缓存锁
319
- - 防止事务执行期间重新缓存脏数据
320
- - 提交/回滚后释放锁
118
+ ---
321
119
 
322
- **使用示例**
120
+ ## 详细变更文档
323
121
 
324
- ```javascript
325
- // 自动管理事务(推荐)
326
- await msq.withTransaction(async (tx) => {
327
- await collection.updateOne(
328
- { _id: 1 },
329
- { $set: { value: 100 } },
330
- { session: tx.session }
331
- );
332
-
333
- // 查询(MongoDB session 确保看到最新数据)
334
- const doc = await collection.findOne(
335
- { _id: 1 },
336
- { session: tx.session }
337
- );
338
- });
122
+ > **说明**: 详细变更文档位于 `changelogs/` 目录
339
123
 
340
- // 手动管理事务
341
- const tx = await msq.startSession();
342
- try {
343
- await tx.start();
344
- await collection.updateOne(..., { session: tx.session });
345
- await tx.commit();
346
- } catch (error) {
347
- await tx.abort();
348
- } finally {
349
- await tx.end();
350
- }
351
124
  ```
352
-
353
- **配置选项**
354
-
355
- ```javascript
356
- const msq = new MonSQLize({
357
- type: 'mongodb',
358
- databaseName: 'mydb',
359
- config: { uri: 'mongodb://localhost:27017' }
360
- });
361
-
362
- // 使用事务
363
- await msq.withTransaction(async (tx) => {
364
- // 事务操作
365
- }, {
366
- readConcern: { level: 'majority' }, // 读关注级别
367
- timeout: 30000, // 超时时间
368
- maxRetries: 3, // 最大重试次数
369
- retryDelay: 100, // 重试延迟
370
- retryBackoff: 2 // 重试退避系数
371
- });
125
+ changelogs/
126
+ ├── TEMPLATE.md # 变更文档模板
127
+ └── v1.0.0.md # v1.0.0 详细变更
372
128
  ```
373
129
 
374
- **技术细节**
375
-
376
- - 使用 `session.__monSQLizeTransaction` 传递 Transaction 实例
377
- - 写操作通过 `getTransactionFromSession()` 获取 Transaction
378
- - ✅ 调用 `tx.recordInvalidation()` 实现写时失效 + 缓存锁
379
- - ✅ 所有原有功能未受影响(24/24 测试全部通过)
130
+ **注意**:
131
+ - changelogs/ 目录包含历史详细变更文档
132
+ - 新版本应优先使用 plans/ 目录存储需求文档
133
+ - STATUS.md 是主要的需求状态追踪文档
380
134
 
381
135
  ---
382
136
 
383
- #### 🎉 事务功能实现(Phase 1-3,100% 完成)(2025-11-19)
384
-
385
- **注意**: 以下为早期实现记录,最新功能请参考上方"完整版"说明
386
-
387
- **更新**: 2025-11-19 - 补充 TypeScript 类型声明,功能已 100% 完成 ✅
388
-
389
- **Phase 1: TransactionManager 核心实现(100% 完成)**
390
-
391
- 1. **核心类实现**(lib/transaction/)
392
- - ✅ `Transaction` 类 - 事务会话包装器
393
- - `commit()` - 提交事务
394
- - `abort()` - 中止事务
395
- - 自动资源清理
396
- - 状态追踪
397
- - ✅ `TransactionManager` 类 - 事务管理器
398
- - `startSession(options)` - 创建手动事务
399
- - `withTransaction(callback, options)` - 自动事务管理
400
- - 缓存失效管理(提交/回滚时)
401
- - `destroy()` - 资源清理
402
- - ✅ `RetryHandler` 类 - 重试逻辑处理器
403
- - 自动重试瞬态错误
404
- - 指数退避策略
405
- - 可配置最大重试次数
406
-
407
- 2. **主入口集成**(Phase 2,100% 完成)
408
- - ✅ `lib/index.js` - MonSQLize 主类
409
- - 构造函数接受 `transaction` 配置选项
410
- - `connect()` 时自动初始化 TransactionManager
411
- - 导出 `startTransaction(options)` 方法
412
- - 导出 `withTransaction(callback, options)` 方法
413
- - `close()` 时清理 TransactionManager
414
-
415
- 3. **CollectionWrapper 扩展**(Phase 3,100% 完成)
416
- - ✅ `lib/mongodb/common/transaction-aware.js` - 事务感知工具
417
- - `isInTransaction(options)` - 检测是否在事务中
418
- - `getSessionInfo(options)` - 获取会话信息
419
- - `makeTransactionAware(operation)` - 包装器工厂
420
- - ✅ 所有写操作已更新(13/13):
421
- - update-one.js, update-many.js
422
- - delete-one.js, delete-many.js
423
- - insert-one.js, insert-many.js, insert-batch.js
424
- - replace-one.js, upsert-one.js, increment-one.js
425
- - find-one-and-update.js, find-one-and-replace.js, find-one-and-delete.js
426
- - ✅ 所有写操作支持 `options.session` 参数
427
- - ✅ 事务中自动跳过缓存失效
428
- - ✅ 非事务操作正常失效缓存
429
-
430
- 4. **TypeScript 类型声明**(新增,100% 完成)
431
- - ✅ `index.d.ts` - 事务相关类型定义
432
- - `MongoSession` 接口 - MongoDB 原生会话类型
433
- - `TransactionOptions` 接口 - 事务配置选项
434
- - `Transaction` 接口 - 事务类类型
435
- - `MonSQLize.startTransaction()` 方法签名
436
- - `MonSQLize.withTransaction()` 方法签名
437
- - `BaseOptions.transaction` 配置选项
438
-
439
- 5. **测试与示例**(100% 完成)
440
- - ✅ `test/transaction.test.js` - 集成测试(16,938 字节)
441
- - ✅ `test/unit/transaction/transaction.test.js` - Transaction 单元测试
442
- - ✅ `test/unit/transaction/transaction-manager.test.js` - TransactionManager 单元测试
443
- - ✅ `test/unit/transaction/cache-lock-manager.test.js` - CacheLockManager 单元测试
444
- - ✅ `examples/transaction.examples.js` - 6个基础示例(349 行)
445
- - ✅ `examples/transaction/basic-usage.js` - 基础用法(5,214 字节)
446
- - ✅ `examples/transaction/advanced-usage.js` - 高级用法(8,870 字节)
447
- - ✅ 测试通过率:24/24(100%)
448
- - ✅ 测试覆盖率:95%+(优于项目标准 70%)
449
-
450
- 6. **文档**(100% 完成)
451
- - ✅ `README.md` - 事务功能章节 + 核心 API 表格
452
- - ✅ `docs/transaction-quickstart.md` - 快速开始指南(7个场景)
453
- - ✅ `design/transaction-implementation-design.md` - 完整设计文档
454
- - ✅ 6个分析报告(进度、总结、验证清单等)
455
- - ✅ `examples/transaction.examples.js` - 6个实战示例
456
- - 手动事务管理
457
- - 自动事务管理(推荐)
458
- - 事务回滚
459
- - 自动重试机制
460
- - 多集合事务
461
- - 事务隔离性
137
+ ## 相关文档
462
138
 
463
- 5. **工具脚本**
464
- - ✅ `lib/mongodb/scripts/apply-transaction-awareness.js` - 批量更新脚本
465
-
466
- **API 使用示例**:
467
- ```javascript
468
- // 初始化时配置事务
469
- const msq = new MonSQLize({
470
- type: 'mongodb',
471
- databaseName: 'mydb',
472
- config: { uri: 'mongodb://localhost:27017' },
473
- transaction: {
474
- maxRetries: 3,
475
- defaultReadConcern: { level: 'snapshot' }
476
- }
477
- });
478
-
479
- await msq.connect();
480
-
481
- // 方式 1: 自动事务管理(推荐)
482
- await msq.withTransaction(async (tx) => {
483
- await collection.updateOne(
484
- { _id: 1 },
485
- { $inc: { balance: -100 } },
486
- { session: tx.session }
487
- );
488
- await collection.updateOne(
489
- { _id: 2 },
490
- { $inc: { balance: 100 } },
491
- { session: tx.session }
492
- );
493
- });
494
-
495
- // 方式 2: 手动事务管理
496
- const tx = await msq.startTransaction();
497
- try {
498
- await collection.updateOne({...}, {...}, { session: tx.session });
499
- await tx.commit();
500
- } catch (error) {
501
- await tx.abort();
502
- throw error;
503
- }
504
- ```
505
-
506
- **核心特性**:
507
- - ✅ 手动事务管理(完整生命周期控制)
508
- - ✅ 自动事务管理(便捷的 callback 模式)
509
- - ✅ 自动重试机制(处理 TransientTransactionError)
510
- - ✅ 事务感知的缓存失效(事务中跳过,提交后批量失效)
511
- - ✅ 会话生命周期管理(自动创建和清理)
512
- - ✅ 完善的错误处理和资源清理
513
-
514
- **系统要求**:
515
- - MongoDB 4.0+ 且部署在副本集或分片集群上
516
- - 单机 MongoDB 不支持事务
517
-
518
- **详细进度报告**:
519
- - 📄 `analysis-reports/2025-01-19-transaction-implementation-progress.md`
139
+ - [STATUS.md](./STATUS.md) - 需求状态追踪
140
+ - [plans/](./plans/README.md) - 需求详细文档
141
+ - [README.md](./README.md) - 项目说明
142
+ - [changelogs/](./changelogs/README.md) - 历史详细变更(供参考)
520
143
 
521
144
  ---
522
145
 
523
- #### 🎉 事务功能 Phase 1 实施完成(2025-11-19)(已整合到上方)
524
-
525
- **已完成内容**:
526
-
527
- 1. **核心类实现**(lib/transaction/)
528
- - ✅ Transaction 类(~310 行)- 事务生命周期管理
529
- - ✅ TransactionManager 类(~260 行)- 事务管理器(含重试、超时、监控)
530
- - ✅ CacheLockManager 类(~130 行)- 缓存锁管理
531
- - ✅ 模块索引(index.js)
532
-
533
- 2. **Cache 扩展**(lib/cache.js)
534
- - ✅ 添加 lockManager 属性和 lockHits 统计
535
- - ✅ set() 方法添加锁检查逻辑
536
- - ✅ setLockManager() 和 invalidate() 方法
537
-
538
- 3. **单元测试**(test/unit/transaction/)
539
- - ✅ Transaction 单元测试(9 个测试组,50+ 断言)
540
- - ✅ CacheLockManager 单元测试(7 个测试组,40+ 断言)
541
- - ✅ TransactionManager 单元测试(8 个测试组,60+ 断言)
542
-
543
- 4. **使用示例**(examples/transaction/)
544
- - ✅ basic-usage.js - 基础使用和回滚示例
545
- - ✅ advanced-usage.js - 重试、监控、隔离级别等 5 个高级示例
546
-
547
- 5. **设计文档**(design/)
548
- - ✅ 完整设计文档(60KB,生产级)
549
- - ✅ 可行性分析和最终确认
550
-
551
- **核心特性**:
552
- - ✅ 基础事务操作(start/commit/abort/end)
553
- - ✅ 自动事务管理(withTransaction)
554
- - ✅ 缓存锁机制(写时失效 + 锁定)
555
- - ✅ 重试机制(自动重试瞬态错误,指数退避)
556
- - ✅ 超时处理(自动中断长事务)
557
- - ✅ 监控指标(执行时长、成功率、重试次数)
558
- - ✅ 优雅降级(异常容错)
559
- - ✅ 读关注/读偏好/因果一致性
560
-
561
- **代码统计**:
562
- - 核心代码:~700 行
563
- - 单元测试:~750 行
564
- - 示例代码:~350 行
565
-
566
- **Phase 2 完成**(2025-11-19):
567
- - ✅ 集成到 MonSQLize 主类
568
- - ✅ 添加 transactionManager 属性
569
- - ✅ 添加 withTransaction() 方法
570
- - ✅ 添加 startTransaction() 方法
571
- - ✅ close() 方法集成清理逻辑
572
- - ✅ 集成测试(test/integration/transaction/)
573
- - ✅ 基础功能测试
574
- - ✅ withTransaction 测试
575
- - ✅ 事务配置测试
576
- - ✅ 手动事务管理测试
577
- - ✅ 统计信息测试
578
- - ✅ API 文档(docs/transaction-api.md)
579
- - ✅ 完整 API 参考
580
- - ✅ 使用示例
581
- - ✅ 最佳实践
582
- - ✅ 常见问题
583
- - ✅ README 更新
584
- - ✅ 添加事务功能说明
585
- - ✅ 添加事务使用示例
586
-
587
- **下一步**(Phase 3-4):
588
- - ⏳ CollectionWrapper 扩展(事务感知)
589
- - ⏳ 性能测试
590
- - ⏳ 最终发布准备
591
-
592
- ---
593
-
594
- #### 事务完整功能 - 设计方案(2025-11-19)✅ Production Ready v3.0
595
-
596
- **🎉 经过三遍完整分析,确认可以达到生产级别!**
597
-
598
- ---
599
-
600
- ### 📋 三遍分析结果
601
-
602
- **第一遍:功能完整性检查**
603
- - ✅ 基础事务操作:完整
604
- - ✅ 缓存锁机制:正确
605
- - ✅ 会话管理:完整
606
- - ✅ 隔离与一致性:完整
607
- - ⚠️ 发现问题:startSession() 会话配置逻辑需修正
608
-
609
- **第二遍:生产级可靠性检查**
610
- - ✅ 事务原子性:正确
611
- - ✅ 缓存一致性:正确
612
- - ✅ 并发安全:正确
613
- - ⚠️ 需要补充:重试机制、超时处理、监控指标
614
-
615
- **第三遍:性能和扩展性检查**
616
- - ✅ 缓存锁开销:合理
617
- - ✅ 事务开销:最小
618
- - ✅ 并发性能:优秀
619
- - ⚠️ 建议补充:优雅降级、连接池管理
620
-
621
- ---
622
-
623
- ### ✅ 核心功能(v1.0.0)
624
-
625
- 1. **基础事务操作**
626
- - `startSession()` - 创建事务会话
627
- - `withTransaction()` - 自动管理事务生命周期(推荐)
628
- - `start()` / `commit()` / `abort()` / `end()` - 完整生命周期
629
-
630
- 2. **事务缓存锁机制**
631
- - 写时无效化(Write-Through Invalidation)
632
- - 缓存锁定(Cache Lock)
633
- - 锁清理机制(定期清理过期锁)
634
-
635
- 3. **会话管理**
636
- - 自动管理(withTransaction)
637
- - 手动管理(startSession)
638
- - 错误处理和回滚
639
-
640
- 4. **隔离与一致性**
641
- - readConcern(local/majority/snapshot)
642
- - readPreference(primary/secondary/nearest)
643
- - causalConsistency(因果一致性)
644
-
645
- ---
646
-
647
- ### 🆕 生产级补充(v1.1.0)
648
-
649
- **经过分析,添加以下必须的生产级特性**:
650
-
651
- 1. **修正:startSession() 会话配置** 🔴 必须
652
- ```javascript
653
- // 修正前(有问题)
654
- const session = await this.adapter.startSession();
655
- if (hasOptions) {
656
- await session.endSession(); // ❌ 先关闭再重建
657
- session = await this.adapter.startSession(options);
658
- }
659
-
660
- // 修正后(正确)
661
- const sessionOptions = buildSessionOptions(options);
662
- const session = await this.adapter.startSession(sessionOptions); // ✅ 直接创建
663
- ```
664
-
665
- 2. **新增:事务重试机制** 🔴 必须
666
- - 自动重试瞬态错误(TransientTransactionError)
667
- - 配置:`enableRetry: true`,`maxRetries: 3`
668
- - 指数退避算法:`retryBackoff: 2`
669
- - 智能错误判断:区分可重试和不可重试错误
670
-
671
- 3. **新增:超时处理机制** 🔴 必须
672
- - 防止长事务占用资源
673
- - 配置:`enableTimeout: true`,`maxDuration: 300000`
674
- - 自动中断:超时自动 abort
675
- - MongoDB 超时:`maxCommitTimeMS`
676
-
677
- 4. **新增:监控指标** 🟠 建议
678
- - 统计执行时长:`avgDuration`, `maxDuration`, `minDuration`
679
- - 统计成功率:`successRate = committed / total`
680
- - 统计重试次数:`totalRetries`, `transientErrors`
681
- - 统计活跃事务:`activeTransactions`
682
- - API:`transactionManager.getStats()`
683
-
684
- 5. **新增:优雅降级** 🟡 可选
685
- - 缓存失效异常:降级继续执行
686
- - 锁定异常:降级继续执行(至少缓存已失效)
687
- - 错误日志:记录降级情况
688
-
689
- ---
690
-
691
- ### 📊 生产级评估
692
-
693
- | 维度 | v1.0.0 | v1.1.0 | 提升 | 评级 |
694
- |------|--------|--------|------|------|
695
- | 功能完整性 | 95% | 100% | +5% | ⭐⭐⭐⭐⭐ |
696
- | 可靠性 | 80% | 100% | +20% | ⭐⭐⭐⭐⭐ |
697
- | 可观测性 | 0% | 100% | +100% | ⭐⭐⭐⭐⭐ |
698
- | 容错能力 | 70% | 95% | +25% | ⭐⭐⭐⭐⭐ |
699
- | **生产可用性** | ⚠️ 可用但有风险 | ✅ **完全可用** | - | ⭐⭐⭐⭐⭐ |
700
-
701
- ---
702
-
703
- ### 📖 完整配置(生产级)
704
-
705
- ```javascript
706
- const msq = new MonSQLize({
707
- type: "mongodb",
708
- databaseName: "mydb",
709
- config: { uri: "mongodb://localhost:27017" },
710
-
711
- transaction: {
712
- // 缓存锁配置
713
- enableCacheLock: true,
714
- maxDuration: 300000,
715
- lockCleanupInterval: 10000,
716
-
717
- // 重试配置 🆕
718
- enableRetry: true,
719
- maxRetries: 3,
720
- retryDelay: 100,
721
- retryBackoff: 2,
722
-
723
- // 超时配置 🆕
724
- enableTimeout: true,
725
-
726
- // 读关注
727
- readConcern: { level: "majority" },
728
-
729
- // 读偏好
730
- readPreference: "primary",
731
-
732
- // 因果一致性
733
- causalConsistency: true
734
- }
735
- });
736
- ```
737
-
738
- ---
739
-
740
- ### 🔧 使用示例
741
-
742
- ```javascript
743
- // 基础使用(自动重试)
744
- await msq.withTransaction(async (tx) => {
745
- const user = await collection.findOne({ _id: 1 }, { session: tx });
746
- await collection.updateOne(
747
- { _id: 1 },
748
- { $set: { balance: 200 } },
749
- { session: tx }
750
- );
751
- });
752
-
753
- // 自定义重试配置
754
- await msq.withTransaction(async (tx) => {
755
- // ...
756
- }, {
757
- maxRetries: 5, // 金融场景:更多重试
758
- maxDuration: 60000 // 短事务:1 分钟
759
- });
760
-
761
- // 监控统计
762
- const stats = msq.transactionManager.getStats();
763
- console.log(`成功率: ${stats.successRate}`);
764
- console.log(`平均时长: ${stats.avgDuration}ms`);
765
- console.log(`总重试: ${stats.totalRetries}`);
766
- ```
767
-
768
- ---
769
-
770
- ### 📅 实施计划(9 天)
771
-
772
- - **Phase 1**: 核心事务功能(3 天)
773
- - Transaction 类
774
- - TransactionManager 类
775
- - 基础测试
776
-
777
- - **Phase 2**: 缓存锁机制(2 天)
778
- - CacheLockManager
779
- - Cache/CollectionWrapper 增强
780
- - 缓存锁测试
781
-
782
- - **Phase 3**: 生产级补充(2 天)🆕
783
- - 重试机制 + 超时处理
784
- - 监控指标 + 优雅降级
785
-
786
- - **Phase 4**: 文档和发布(2 天)
787
- - API 文档
788
- - 使用示例
789
- - 性能测试
790
-
791
- ---
792
-
793
- ### 📄 相关文件
794
-
795
- - **`design/transaction-complete-design.md`** - ✅ 事务完整设计(v1.0.0)
796
- - **`design/transaction-production-supplement.md`** - ✅ 生产级补充(v1.1.0)**NEW**
797
- - **`design/README.md`** - ✅ 设计文档索引(v3.0.0)
798
- - `analysis-reports/2025-11-18-transaction-cache-lock-ABSOLUTE-FINAL.md` - ✅ 缓存锁验证
799
- - `analysis-reports/2025-11-18-transaction-write-through-invalidation.md` - ✅ 写时无效化
800
- - `analysis-reports/2025-11-18-lock-cleanup-mechanism-explained.md` - ✅ 锁清理机制
801
-
802
- ---
803
-
804
- ### ✅ 验收标准(生产级)
805
-
806
- **功能完整性(100%)**:
807
- - [ ] 所有基础事务操作实现
808
- - [ ] 缓存锁机制实现
809
- - [ ] 重试机制实现 🆕
810
- - [ ] 超时处理实现 🆕
811
- - [ ] 监控指标实现 🆕
812
- - [ ] 优雅降级实现 🆕
813
-
814
- **测试覆盖率(≥ 70%)**:
815
- - [ ] 单元测试 ≥ 70%
816
- - [ ] 集成测试覆盖核心场景
817
- - [ ] 重试机制测试
818
- - [ ] 超时处理测试
819
- - [ ] 监控指标测试
820
- - [ ] 并发测试(100+ 并发)
821
-
822
- **性能要求**:
823
- - [ ] 事务开销 < 10%
824
- - [ ] 缓存锁开销 < 10%
825
- - [ ] 重试开销合理
826
- - [ ] 无内存泄漏
827
- - [ ] 长时间运行稳定(24 小时)
828
-
829
- **生产级验证**:
830
- - [ ] 可靠性:100%(重试+超时+容错)
831
- - [ ] 可观测性:100%(监控指标)
832
- - [ ] 容错能力:95%(优雅降级)
833
-
834
- ---
835
-
836
- ### 🎉 最终结论
837
-
838
- **✅ 当前方案(v2.0 生产级)完全可以达到生产级别!**
839
-
840
- | 维度 | 评分 | 说明 |
841
- |------|------|------|
842
- | 功能完整性 | 100% | 所有功能实现 ✅ |
843
- | 可靠性 | 100% | 重试+超时+容错 ✅ |
844
- | 可观测性 | 100% | 完整监控指标 ✅ |
845
- | 容错能力 | 95% | 优雅降级 ✅ |
846
- | 性能表现 | 90% | 开销 < 10% ✅ |
847
-
848
- **适用场景**:
849
- - ✅ 金融支付系统(高可靠)
850
- - ✅ 电商订单系统(高并发)
851
- - ✅ 社交平台系统(高性能)
852
- - ✅ 企业应用系统(通用)
853
-
854
- **实施计划**:
855
- - 预计工期:9 天(原 7 天 + 生产级补充 2 天)
856
- - 文档位置:`design/transaction-complete-design.md`
857
-
858
- **可以立即开始实施!** 🚀
859
-
860
- ---
861
-
862
- ### 🙏 致谢
863
-
864
- 感谢用户的严格要求和持续审查:
865
- 1. 指出需要完整的事务设计(不只是缓存锁)
866
- 2. 要求三遍分析确认生产级
867
- 3. 要求整合所有文档为最终方案
868
- 4. 帮助发现和修正问题
869
-
870
- **经过完整的设计、三遍分析、修复和整合,现在的方案完全满足生产级要求。**
871
-
872
- **经过 5 遍完整分析和严格验证,确保 100% 正确**
873
-
874
- ---
875
-
876
- ### 🎯 核心机制(最终确认)
877
-
878
- **两个机制缺一不可**:
879
- 1. **写时失效**:防止事务执行期间读到缓存中的旧数据
880
- 2. **缓存锁定**:防止缓存过期后被重新缓存脏数据
881
-
882
- ```
883
- 仅锁定 → ❌ 事务期间读到缓存旧数据
884
- 仅失效 → ❌ 缓存过期后重新缓存脏数据
885
- 失效+锁定 → ✅ 完美解决
886
- ```
887
-
888
- ---
889
-
890
- ### 💻 核心实现
891
-
892
- **Transaction.recordInvalidation()**(写时失效 + 锁定):
893
- ```javascript
894
- async recordInvalidation(cacheKey) {
895
- // 1. 立即失效缓存(写时失效)
896
- await this.cache.invalidate(cacheKey);
897
-
898
- // 2. 锁定缓存键(防止重新缓存)
899
- if (this.config.lockManager) {
900
- this.config.lockManager.lock(this.id, cacheKey, this.config.maxDuration);
901
- this.lockedKeys.add(cacheKey);
902
- }
903
-
904
- // 3. 记录到待处理列表
905
- this.pendingInvalidations.add(cacheKey);
906
- }
907
- ```
908
-
909
- **Transaction.commit()**(只解锁):
910
- ```javascript
911
- async commit() {
912
- await this.session.commitTransaction();
913
- this.state = "committed";
914
-
915
- // 缓存已在 recordInvalidation() 中失效,这里只解锁
916
- this._unlockAllKeys();
917
- this.pendingInvalidations.clear();
918
- }
919
- ```
920
-
921
- **Transaction.abort()**(只解锁):
922
- ```javascript
923
- async abort() {
924
- await this.session.abortTransaction();
925
- this.state = "aborted";
926
-
927
- // 缓存已失效,但数据未改变
928
- // 解锁后,下次查询会从数据库读取并重新缓存(正确的旧值)
929
- this.pendingInvalidations.clear();
930
- this._unlockAllKeys();
931
- }
932
- ```
933
-
934
- ---
935
-
936
- ### 📊 完整时间轴验证
937
-
938
- **正常提交场景**:
939
- ```
940
- T=0s: 缓存: balance=100
941
- T=10s: 事务更新 → ❌ 立即失效 → 🔒 锁定
942
- T=15s: 其他请求 → cache miss → 查DB(100) ✅ → 尝试缓存 → 🔒 不缓存
943
- T=60s: (缓存已失效,无影响)
944
- T=70s: 其他请求 → cache miss → 查DB(100) ✅ → 尝试缓存 → 🔒 不缓存
945
- T=90s: 事务提交 → 🔓 解锁
946
- T=95s: 其他请求 → cache miss → 查DB(200) ✅ → 缓存成功
947
-
948
- ✅ 全程无脏读
949
- ```
950
-
951
- **回滚场景**:
952
- ```
953
- T=0s: 缓存: balance=100
954
- T=10s: 事务更新 → ❌ 立即失效 → 🔒 锁定
955
- T=15s: 其他请求 → cache miss → 查DB(100) ✅
956
- T=90s: 事务回滚 → 🔓 解锁(数据仍是100)
957
- T=95s: 其他请求 → cache miss → 查DB(100) ✅ → 缓存成功
958
-
959
- ✅ 缓存自然恢复
960
- ```
961
-
962
- ---
963
-
964
- ### ✅ 验收标准(100% 通过)
965
-
966
- **功能正确性**:
967
- - [x] 写操作立即失效缓存 ✅
968
- - [x] 写操作立即锁定缓存键 ✅
969
- - [x] 其他请求无法重新缓存被锁定的键 ✅
970
- - [x] 提交时只解锁 ✅
971
- - [x] 回滚时只解锁 ✅
972
- - [x] 无锁泄漏 ✅
973
- - [x] 过期锁自动清理 ✅
974
-
975
- **场景验证**:
976
- - [x] 正常提交场景:全程无脏读 ✅
977
- - [x] 回滚场景:缓存自然恢复 ✅
978
- - [x] 长事务场景:缓存过期后无法重新缓存 ✅
979
- - [x] 并发事务场景:锁定独立互不影响 ✅
980
- - [x] 锁过期场景:自动清理 ✅
981
- - [x] 同一键多次更新:无副作用 ✅
982
-
983
- **边界情况**:
984
- - [x] 事务执行期间缓存过期 ✅
985
- - [x] 其他请求尝试重新缓存 ✅
986
- - [x] 事务回滚后缓存恢复 ✅
987
-
988
- ---
989
-
990
- ### 📋 实施清单
991
-
992
- **5 个组件**:
993
- 1. CacheLockManager(~100 行)
994
- 2. Transaction(~80 行)
995
- 3. Cache(~30 行修改)
996
- 4. CollectionWrapper(~80 行修改)
997
- 5. TransactionManager(~50 行修改)
998
-
999
- **总代码量**:~340 行
1000
- **实施时间**:6 天
1001
- **测试覆盖率**:100%
1002
-
1003
- ---
1004
-
1005
- ### ⚙️ 配置
1006
-
1007
- ```javascript
1008
- const msq = new MonSQLize({
1009
- transaction: {
1010
- enableCacheLock: true, // 是否启用缓存锁(默认: true)
1011
- maxDuration: 300000, // 事务最大执行时间(默认: 5 分钟)
1012
- lockCleanupInterval: 10000 // 锁清理间隔(默认: 10 秒)
1013
- }
1014
- });
1015
- ```
1016
-
1017
- ---
1018
-
1019
- ### 📄 相关文件
1020
-
1021
- - **`design/transaction-complete-design.md`** - ✅ 事务完整设计文档(主文档,包含所有功能)**NEW**
1022
- - **`design/transaction-cache-lock-design.md`** - ✅ 缓存锁详细设计(子模块)
1023
- - **`design/README.md`** - ✅ 设计文档索引和导航
1024
- - `analysis-reports/2025-11-18-transaction-cache-lock-ABSOLUTE-FINAL.md` - ✅ 缓存锁最终方案(经过 5 遍验证)
1025
- - `analysis-reports/2025-11-18-transaction-write-through-invalidation.md` - ✅ 写时无效化详细说明
1026
- - `analysis-reports/2025-11-18-lock-cleanup-mechanism-explained.md` - ✅ 锁清理机制详解
1027
-
1028
- ---
1029
-
1030
- ### 🎯 核心要点总结
1031
-
1032
- 1. 缓存在事务外配置:`{ cache: 60000 }`
1033
- 2. 事务内查询不需要 cache 参数:`{ session: tx }`
1034
- 3. 写操作立即失效 + 锁定:`recordInvalidation()`
1035
- 4. 其他请求无法重新缓存:`isLocked() → 不缓存`
1036
- 5. 提交时只解锁:`unlock()`
1037
- 6. 回滚时只解锁:`unlock()`
1038
-
1039
- ---
1040
-
1041
- ### 🙏 致谢
1042
-
1043
- **深深感谢用户的极度严格审查!**
1044
-
1045
- 经过多次纠正和 5 遍完整验证:
1046
- - v1.0-v3.0: 各种理解错误 ❌
1047
- - FINAL v1: 仅锁定,未失效缓存 ❌
1048
- - FINAL v2: 添加写时无效化 ✅
1049
- - **ABSOLUTE FINAL: 经过 5 遍验证,100% 正确 ✅✅✅**
1050
-
1051
- 用户的每次质疑都让方案更加严谨,最终达到了可以实施的标准。
1052
-
1053
- **我对这个方案有 100% 的信心。** 💯
1054
-
1055
- **关键更新**:添加写时无效化(Write-Through Invalidation)机制
1056
-
1057
- ---
1058
-
1059
- ### 🚨 发现的新问题
1060
-
1061
- 用户指出:"写时无效化 → 事务提交前不允许写缓存,事务提交后再刷新 这部分限制呢?"
1062
-
1063
- **问题分析**:
1064
- ```
1065
- 之前的方案(仅锁定):
1066
- T=10s: 事务更新 balance → 200,🔒 锁定缓存键
1067
- 但缓存仍然存在(balance: 100)
1068
- T=15s: 其他请求查询
1069
- → cache.get() → 返回 100 ❌ 脏读!
1070
- T=90s: 事务提交 → 失效缓存
1071
-
1072
- 问题:事务执行期间,其他请求可能读到缓存中的脏数据
1073
- ```
1074
-
1075
- ---
1076
-
1077
- ### ✅ 解决方案:写时无效化
1078
-
1079
- **核心机制**:
1080
- 1. **写操作时立即失效缓存**:`await this.cache.invalidate(cacheKey)`
1081
- 2. **锁定缓存键**:防止事务执行期间重新缓存
1082
- 3. **事务提交时只解锁**:缓存已在写时失效,无需再次失效
1083
- 4. **事务回滚时只解锁**:缓存已失效,下次查询会自然恢复
1084
-
1085
- **时间轴**:
1086
- ```
1087
- T=0s: 缓存有数据(balance: 100)
1088
- T=10s: 事务更新 balance → 200
1089
- → ❌ 立即失效缓存(balance: 100 被删除)
1090
- → 🔒 锁定缓存键
1091
- T=15s: 其他请求查询
1092
- → cache.get() → undefined(缓存已失效)
1093
- → 查数据库 → balance: 100 ✅ 正确(事务未提交)
1094
- → 尝试缓存 → 检测到锁定 → 不缓存
1095
- T=90s: 事务提交
1096
- → 🔓 解锁(缓存已在 T=10s 失效)
1097
- T=95s: 其他请求查询
1098
- → cache.get() → undefined
1099
- → 查数据库 → balance: 200 ✅ 正确(事务已提交)
1100
- → 缓存 → balance: 200 ✅
1101
-
1102
- ✅ 全程无脏读!
1103
- ```
1104
-
1105
- ---
1106
-
1107
- ### 💻 代码更新
1108
-
1109
- **Transaction.recordInvalidation()** (更新):
1110
- ```javascript
1111
- async recordInvalidation(cacheKey) {
1112
- // 1. 立即失效缓存(写时无效化)
1113
- await this.cache.invalidate(cacheKey);
1114
-
1115
- // 2. 锁定该键(防止重新缓存)
1116
- if (this.config.lockManager) {
1117
- this.config.lockManager.lock(this.id, cacheKey, this.config.maxDuration);
1118
- this.lockedKeys.add(cacheKey);
1119
- }
1120
-
1121
- // 3. 记录到待处理列表
1122
- this.pendingInvalidations.add(cacheKey);
1123
- }
1124
- ```
1125
-
1126
- **Transaction.commit()** (更新):
1127
- ```javascript
1128
- async commit() {
1129
- await this.session.commitTransaction();
1130
- this.state = "committed";
1131
-
1132
- // 提交时只需要解锁(缓存已在写时失效)
1133
- this._unlockAllKeys();
1134
- this.pendingInvalidations.clear();
1135
- }
1136
- ```
1137
-
1138
- **Transaction.abort()** (更新):
1139
- ```javascript
1140
- async abort() {
1141
- await this.session.abortTransaction();
1142
- this.state = "aborted";
1143
-
1144
- // 回滚时只解锁(缓存已失效,下次查询会自然恢复)
1145
- this.pendingInvalidations.clear();
1146
- this._unlockAllKeys();
1147
- }
1148
- ```
1149
-
1150
- ---
1151
-
1152
- ### 🎯 关键优势
1153
-
1154
- 1. **防止脏读**
1155
- - 事务内写操作后,立即失效缓存
1156
- - 其他请求查询时,cache miss → 查数据库
1157
- - 读到的是数据库中的值(正确)
1158
-
1159
- 2. **事务隔离性**
1160
- - 符合 Read Committed 隔离级别
1161
- - 事务内修改对外不可见(缓存已失效)
1162
-
1163
- 3. **一致性保证**
1164
- - 缓存中的数据要么不存在,要么是正确的
1165
- - 不会出现缓存与数据库不一致的情况
1166
-
1167
- ---
1168
-
1169
- ### 📄 相关文件
1170
-
1171
- - `analysis-reports/2025-11-18-transaction-write-through-invalidation.md` - ✅ 写时无效化详细说明
1172
- - `analysis-reports/2025-11-18-transaction-cache-lock-FINAL-IMPLEMENTATION.md` - ✅ 已更新
1173
-
1174
- ---
1175
-
1176
- ### 🙏 感谢
1177
-
1178
- **再次感谢用户的细致审查!**
1179
-
1180
- 指出了"写时无效化"这个关键机制,避免了事务执行期间的脏读问题。
1181
-
1182
- 方案演进:
1183
- - v1.0-v3.0: 各种理解错误 ❌
1184
- - FINAL v1: 仅锁定,未失效缓存 ❌(脏读)
1185
- - **FINAL v2: 写时无效化 + 锁定 ✅(完全正确)**
1186
-
1187
- **经过 5 次完整分析和多次纠正,最终确定的正确方案**
1188
-
1189
- ---
1190
-
1191
- ### 📋 核心问题
1192
-
1193
- 事务执行时间可能超过缓存 TTL,导致缓存过期后被其他请求重新缓存脏数据。
1194
-
1195
- **时间轴**:
1196
- ```
1197
- T=0s: 缓存有数据(balance: 100,TTL: 60s)
1198
- T=10s: 事务开始,更新 balance → 200,🔒 锁定缓存键
1199
- T=60s: 缓存过期(被删除)
1200
- T=70s: 其他请求查询 → 查数据库 → 尝试缓存
1201
- → 检测到锁定 → ❌ 不缓存(避免脏数据)
1202
- T=90s: 事务提交 → 失效缓存 → 🔓 解锁
1203
- ```
1204
-
1205
- ---
1206
-
1207
- ### 🎯 解决方案:缓存锁机制
1208
-
1209
- **核心原则**:
1210
- 1. **缓存在事务外配置**:`await collection.findOne({ _id: 1 }, { cache: 60000 })`
1211
- 2. **事务内查询不需要 cache 参数**:`await collection.findOne({ _id: 1 }, { session: tx })`
1212
- 3. **事务内查询只读缓存,不写缓存**:如果缓存存在就用,不存在就查数据库但不缓存
1213
- 4. **写操作自动锁定**:`updateOne/deleteOne` 自动调用 `recordInvalidation()` + 锁定缓存键
1214
- 5. **其他请求检查锁定状态**:`cache.set()` 检查 `isLocked()`,如果被锁定则不缓存
1215
- 6. **事务提交失效并解锁**:失效缓存 + 解锁所有键
1216
- 7. **事务回滚只解锁**:不失效缓存(数据未改变)+ 解锁所有键
1217
-
1218
- ---
1219
-
1220
- ### 💻 实现组件
1221
-
1222
- **需要实现的 5 个组件**:
1223
-
1224
- 1. **CacheLockManager**(新增,~100 行)
1225
- - 管理缓存键的锁定状态
1226
- - 定期清理过期的锁
1227
- - 方法:`lock()`, `unlock()`, `isLocked()`
1228
-
1229
- 2. **Transaction**(增强,~80 行)
1230
- - 记录需要失效的缓存
1231
- - 锁定/解锁缓存键
1232
- - 方法:`recordInvalidation()`, `commit()`, `abort()`
1233
-
1234
- 3. **Cache**(增强,~30 行)
1235
- - `set()` 检查锁定状态
1236
- - 被锁定时不缓存
1237
- - 统计 `lockHits`
1238
-
1239
- 4. **CollectionWrapper**(增强,~80 行)
1240
- - 事务内查询:读缓存,不写缓存
1241
- - 事务内写操作:调用 `recordInvalidation()`
1242
- - 事务外查询/写操作:正常逻辑
1243
-
1244
- 5. **TransactionManager**(增强,~50 行)
1245
- - 初始化 CacheLockManager
1246
- - 传递配置到 Transaction
1247
-
1248
- **总代码量**:~340 行
1249
-
1250
- ---
1251
-
1252
- ### ⚙️ 配置(极简)
1253
-
1254
- ```javascript
1255
- const msq = new MonSQLize({
1256
- type: "mongodb",
1257
- databaseName: "mydb",
1258
- config: { uri: "mongodb://localhost:27017" },
1259
-
1260
- transaction: {
1261
- enableCacheLock: true, // 是否启用缓存锁(默认: true)
1262
- maxDuration: 300000 // 事务最大执行时间(默认: 5 分钟)
1263
- }
1264
- });
1265
- ```
1266
-
1267
- ---
1268
-
1269
- ### 📖 使用示例
1270
-
1271
- ```javascript
1272
- const collection = msq.collection("accounts");
1273
-
1274
- // 步骤1: 事务外查询(配置缓存)
1275
- const account = await collection.findOne(
1276
- { _id: "A" },
1277
- { cache: 60000 } // ✅ 在事务外配置缓存
1278
- );
1279
-
1280
- // 步骤2: 执行事务
1281
- await msq.withTransaction(async (tx) => {
1282
- // 查询(使用已有缓存,不需要 cache 参数)
1283
- const accountA = await collection.findOne(
1284
- { _id: "A" },
1285
- { session: tx } // ✅ 不需要 cache 参数
1286
- );
1287
-
1288
- // 写操作(自动锁定缓存键)
1289
- await collection.updateOne(
1290
- { _id: "A" },
1291
- { $inc: { balance: -100 } },
1292
- { session: tx } // ✅ 自动记录失效 + 🔒 锁定
1293
- );
1294
- });
1295
- // ✅ 提交时:失效缓存 + 🔓 解锁
1296
- ```
1297
-
1298
- ---
1299
-
1300
- ### 📅 实施计划
1301
-
1302
- - **Phase 1**: 核心实现(2 天)
1303
- - CacheLockManager + Transaction 增强
1304
- - **Phase 2**: 集成和测试(2 天)
1305
- - Cache + CollectionWrapper + TransactionManager 增强
1306
- - **Phase 3**: 文档和发布(2 天)
1307
- - API 文档 + 使用示例 + 性能测试
1308
-
1309
- **总计**: 6 天
1310
-
1311
- ---
1312
-
1313
- ### ✅ 验收标准
1314
-
1315
- - [ ] 功能完整(5 个组件全部实现)
1316
- - [ ] 测试覆盖率 ≥ 70%
1317
- - [ ] TTL 冲突测试通过
1318
- - [ ] 无锁泄漏
1319
- - [ ] 文档完整
1320
-
1321
- ---
1322
-
1323
- ### 📄 相关文件
1324
-
1325
- - `analysis-reports/2025-11-18-transaction-cache-lock-FINAL-IMPLEMENTATION.md` - ✅ 最终可实施方案(核心文档)
1326
- - `analysis-reports/2025-11-18-transaction-cache-lock-final-understanding.md` - ✅ 最终正确理解
1327
- - `analysis-reports/2025-11-18-transaction-cache-lock-correct-design.md` - ✅ 正确设计(已更新)
1328
- - `analysis-reports/2025-11-18-transaction-cache-lock-visual-summary.md` - ✅ 可视化总结(已更新)
1329
-
1330
- ---
1331
-
1332
- ### 🙏 感谢
1333
-
1334
- **深深感谢用户的持续追问和纠正!**
1335
-
1336
- 经过多次纠正:
1337
- - v1.0: 配置混淆 ❌
1338
- - v2.0: 理解错误(事务内自动缓存)❌
1339
- - v3.0: 理解正确(缓存锁机制)✅ 但示例仍有误 ❌
1340
- - v3.1: 完全正确(缓存在事务外配置)✅
1341
- - **FINAL: 可实施方案(经过 5 遍分析)✅✅✅**
1342
-
1343
- 用户的每次质疑都让方案更加正确,最终达到了完全清晰、可实施的状态。
1344
- - **再次纠正**:感谢用户持续追问
1345
- - 用户质疑:"为什么事务内查询还需要 cache: 60000?"
1346
- - ✅ 正确:缓存在**事务外**配置,不是在事务内配置
1347
-
1348
- - **最终正确的理解**:
1349
- ```
1350
- 1. 事务外查询:配置 cache 参数 → 缓存数据
1351
- await collection.findOne({ _id: 1 }, { cache: 60000 });
1352
-
1353
- 2. 事务内查询:不需要配置 cache 参数
1354
- await collection.findOne({ _id: 1 }, { session: tx });
1355
- → 如果缓存存在:返回缓存数据
1356
- → 如果缓存不存在:查数据库(但不缓存)
1357
-
1358
- 3. 事务内写操作:记录失效 + 🔒 锁定缓存键
1359
-
1360
- 4. 其他请求:尝试缓存时检查锁定状态
1361
- → 如果被锁定:不缓存(避免脏数据)
1362
- ```
1363
-
1364
- - **核心原则**:
1365
- - ✅ 缓存在事务外配置
1366
- - ✅ 事务内查询只读缓存,不写缓存
1367
- - ✅ 写操作锁定缓存键
1368
- - ✅ 其他请求检查锁定状态
1369
-
1370
- - **CollectionWrapper.findOne() 正确逻辑**:
1371
- ```javascript
1372
- // 事务内查询
1373
- if (session && session instanceof Transaction) {
1374
- const cached = await this.cache.get(cacheKey);
1375
- if (cached) return cached; // 使用缓存
1376
-
1377
- const result = await this.collection.findOne(filter, { session });
1378
- // 🔑 不缓存结果(因为在事务中)
1379
- return result;
1380
- }
1381
-
1382
- // 事务外查询
1383
- if (cacheOption) {
1384
- const cached = await this.cache.get(cacheKey);
1385
- if (cached) return cached;
1386
-
1387
- const result = await this.collection.findOne(filter);
1388
- await this.cache.set(cacheKey, result, ttl); // 缓存结果
1389
- return result;
1390
- }
1391
- ```
1392
-
1393
- - **配置(最终版,极简)**:
1394
- ```javascript
1395
- const msq = new MonSQLize({
1396
- transaction: {
1397
- enableCacheLock: true, // 启用缓存锁(默认: true)
1398
- maxDuration: 300000 // 最大执行时间(默认: 5 分钟)
1399
- }
1400
- });
1401
- ```
1402
-
1403
- - **使用示例(最终版)**:
1404
- ```javascript
1405
- // 事务外:配置缓存
1406
- const user = await collection.findOne({ _id: 1 }, { cache: 60000 });
1407
-
1408
- // 事务内:不需要配置缓存
1409
- await msq.withTransaction(async (tx) => {
1410
- const user = await collection.findOne(
1411
- { _id: 1 },
1412
- { session: tx } // ← 不需要 cache 参数
1413
- );
1414
-
1415
- await collection.updateOne(
1416
- { _id: 1 },
1417
- { $set: { balance: 200 } },
1418
- { session: tx } // ← 自动锁定
1419
- );
1420
- });
1421
- ```
1422
-
1423
- - **vs v3.0 的改进**:
1424
- ```
1425
- v3.0(部分正确):
1426
- • 理解了缓存锁的目的 ✅
1427
- • 但示例中仍写了 cache: 60000 ❌
1428
- • 逻辑仍然混淆
1429
-
1430
- v3.1(完全正确):
1431
- • 缓存在事务外配置 ✅
1432
- • 事务内查询不需要 cache 参数 ✅
1433
- • 事务内只读缓存,不写缓存 ✅
1434
- • 逻辑完全清晰 ✅
1435
- ```
1436
-
1437
- - **相关文件**:
1438
- - `analysis-reports/2025-11-18-transaction-cache-lock-final-understanding.md` - ✅ 最终正确理解(核心文档)
1439
- - `analysis-reports/2025-11-18-transaction-cache-lock-correct-design.md` - ✅ 已更新
1440
- - `analysis-reports/2025-11-18-transaction-cache-lock-visual-summary.md` - ✅ 已更新
1441
-
1442
- - **深深感谢用户的持续追问!** 🙏🙏🙏
1443
- - 每次质疑都让方案更正确
1444
- - 最终达到了完全清晰的理解
1445
- - 这是真正的最终版本
1446
- - **核心纠正**:感谢用户指出根本性理解错误
1447
- - ❌ 错误理解:事务内查询需要自动缓存
1448
- - ✅ 正确理解:缓存锁是为了防止缓存过期后被重新缓存脏数据
1449
-
1450
- - **正确的设计思路**:
1451
- ```
1452
- 1. 事务外查询:正常缓存逻辑(配置 cache 参数就缓存)
1453
- 2. 事务内查询:正常缓存逻辑(配置 cache 参数就缓存)
1454
- 3. 事务内写操作:记录失效 + 🔒 锁定缓存键
1455
- 4. 其他请求:尝试缓存时检查锁定状态,如果被锁定则不缓存
1456
- ```
1457
-
1458
- - **配置(极简)**:
1459
- ```javascript
1460
- const msq = new MonSQLize({
1461
- transaction: {
1462
- enableCacheLock: true, // 启用缓存锁(默认: true)
1463
- maxDuration: 300000 // 最大执行时间(默认: 5 分钟)
1464
- }
1465
- });
1466
- ```
1467
-
1468
- - **使用(无需特殊处理)**:
1469
- ```javascript
1470
- await msq.withTransaction(async (tx) => {
1471
- // 查询:正常缓存逻辑
1472
- const user = await collection.findOne(
1473
- { _id: 1 },
1474
- { session: tx, cache: 60000 } // ← 配置了就缓存
1475
- );
1476
-
1477
- // 写操作:自动锁定
1478
- await collection.updateOne(
1479
- { _id: 1 },
1480
- { $set: { balance: 200 } },
1481
- { session: tx } // ← 自动记录失效 + 锁定
1482
- );
1483
- });
1484
- ```
1485
-
1486
- - **核心机制**:
1487
- - 写操作时:lockManager.lock(cacheKey) 🔒
1488
- - 其他请求缓存时:检查 isLocked() → 如果锁定则不缓存
1489
- - 事务提交时:invalidate() + unlock() 🔓
1490
- - 事务回滚时:unlock()(不失效缓存)
1491
-
1492
- - **完整流程示例**:
1493
- ```
1494
- T=0s: 缓存有数据(balance: 100,TTL: 60s)
1495
- T=10s: 事务开始 → updateOne → 🔒 锁定缓存键
1496
- T=60s: 缓存过期(被删除)
1497
- T=70s: 其他请求查询 → 查数据库 → 尝试缓存
1498
- → 检测到锁定 → ❌ 不缓存(避免脏数据)
1499
- T=90s: 事务提交 → 失效缓存 → 🔓 解锁
1500
- T=95s: 其他请求查询 → 查数据库 → 缓存成功 ✅
1501
- ```
1502
-
1503
- - **关键优势**:
1504
- - ✅ 配置极简(只需 2 个参数)
1505
- - ✅ 使用简单(事务内外查询逻辑一致)
1506
- - ✅ 防止脏数据(锁定期间不缓存)
1507
- - ✅ 性能影响最小(只影响被锁定的键)
1508
-
1509
- - **vs v2.0 错误方案**:
1510
- ```
1511
- v2.0(错误):
1512
- • enableCache: true → 事务内查询自动缓存 ❌
1513
- • defaultCacheTTL: 60000 → 默认缓存时间 ❌
1514
- • 逻辑复杂、理解错误
1515
-
1516
- v3.0(正确):
1517
- • enableCacheLock: true → 启用缓存锁机制 ✅
1518
- • 事务内外查询逻辑一致 ✅
1519
- • 只在写操作时加锁 ✅
1520
- ```
1521
-
1522
- - **实施计划**:
1523
- - Phase 1: CacheLockManager(2 天)
1524
- - Phase 2: Transaction + Cache 增强(2 天)
1525
- - Phase 3: 测试和文档(2 天)
1526
- - 总计:6 天(vs v2.0 的 9 天)
1527
-
1528
- - **相关文件**:
1529
- - `analysis-reports/2025-11-18-transaction-cache-lock-correct-design.md` - ✅ 最终正确方案(核心文档)
1530
- - `analysis-reports/2025-11-18-transaction-cache-final-design.md` - ⚠️ v2.0(错误理解,已废弃)
1531
- - `analysis-reports/2025-11-18-transaction-cache-evolution-summary.md` - ⚠️ v1.0→v2.0 演进(已废弃)
1532
-
1533
- - **深深感谢用户的纠正!** 🙏
1534
- - 指出了根本性的理解错误
1535
- - 让方案回到正确的轨道
1536
- - 避免了实施错误的设计
1537
-
1538
- - ~~**事务缓存最终设计方案 v2.0**(2025-11-18)~~ ⚠️ 已废弃(理解错误)
1539
- - **核心改进**:简化配置,消除混淆
1540
- - 旧方案问题:`cacheInTransaction: true` + 每次都要写 `cache: 60000`
1541
- - 新方案:`enableCache: true` + `defaultCacheTTL: 60000`
1542
- - 结果:大多数情况不需要写 cache 参数
1543
-
1544
- - **配置层级简化**:
1545
- - 层级 1(全局):`transaction.enableCache` + `defaultCacheTTL`
1546
- - 层级 2(操作):`cache: false/true/60000`(可选覆盖)
1547
- - 减少混淆,符合直觉
1548
-
1549
- - **使用示例**:
1550
- ```javascript
1551
- // 配置一次
1552
- const msq = new MonSQLize({
1553
- transaction: {
1554
- enableCache: true, // 启用缓存
1555
- defaultCacheTTL: 60000, // 默认 60 秒
1556
- cacheStrategy: "lock"
1557
- }
1558
- });
1559
-
1560
- // 使用时不需要写 cache 参数
1561
- await msq.withTransaction(async (tx) => {
1562
- // ✅ 自动使用缓存(60 秒)
1563
- const product = await collection.findOne(
1564
- { _id: "product_123" },
1565
- { session: tx } // ← 不需要写 cache: 60000
1566
- );
1567
-
1568
- // ✅ 可选:覆盖 TTL
1569
- const config = await collection.findOne(
1570
- { key: "rate" },
1571
- { session: tx, cache: 300000 } // ← 缓存 5 分钟
1572
- );
1573
-
1574
- // ✅ 可选:明确不缓存
1575
- const balance = await collection.findOne(
1576
- { _id: userId },
1577
- { session: tx, cache: false } // ← 不缓存
1578
- );
1579
- });
1580
- ```
1581
-
1582
- - **核心优势**:
1583
- - ✅ 配置清晰(一次配置,全局生效)
1584
- - ✅ 易用性高(大多数情况零配置)
1585
- - ✅ 灵活性强(支持单个查询覆盖)
1586
- - ✅ 代码简洁(减少重复)
1587
-
1588
- - **实施计划优化**:
1589
- - Phase 1: 核心实现(5 天,减少 2 天)
1590
- - Phase 2: 文档和示例(2 天,减少 1 天)
1591
- - Phase 3: 测试和发布(2 天)
1592
- - 总计:9 天(vs 旧方案 12 天)
1593
-
1594
- - **相关文件**:
1595
- - `analysis-reports/2025-11-18-transaction-cache-final-design.md` - 🎯 最终方案(推荐阅读)
1596
- - `analysis-reports/2025-11-18-transaction-cache-comprehensive-solution.md` - v1.0 方案(已废弃)
1597
- - `analysis-reports/2025-11-18-transaction-cache-quick-reference.md` - 快速参考(待更新)
1598
-
1599
- - **感谢用户指出配置混淆问题!** 🙏
1600
- - 促使我们重新审视设计
1601
- - 简化后的方案更清晰、更易用
1602
- - 这是一个重要的用户体验改进
1603
-
1604
- - **事务缓存综合解决方案 v1.0**(2025-11-18)~~已废弃~~
1605
- - ⚠️ 该方案已被 v2.0 简化方案取代
1606
- - 问题:配置重复、用户混淆
1607
- - 保留文件供参考,但不推荐实施
1608
-
1609
- - **事务功能最小化实施方案**(2025-11-18)✅ **最终决策:实施**
1610
- - 重新评估后决定实施最小化方案(v0.3.0,3.5 周)
1611
- - 相关文件:
1612
- - `analysis-reports/2025-11-18-transactions-minimal-implementation-plan.md` - 可实施方案(已更新)
1613
- - **核心创新**: 🌟 **事务感知的智能缓存**(独特竞争力)
1614
- - 延迟失效:事务内操作不立即失效缓存,提交时批量失效(性能优化)
1615
- - 事务级缓存:事务内查询使用独立缓存,不污染全局缓存(正确性)
1616
- - 智能失效:自动分析操作影响范围,精确失效相关缓存(效率)
1617
- - 正确性保证:回滚时不失效缓存(一致性)
1618
- - **缓存锁定:防止 TTL 冲突导致的脏读(新增)**
1619
- - **竞争力提升**:
1620
- - Mongoose: 有事务,❌ 无缓存
1621
- - TypeORM: 有事务,❌ 无缓存
1622
- - **monSQLize**: 有事务 + ✅ 有缓存 + ✅ 性能最优
1623
- - **最小化方案**(3.5 周 vs 完整方案 15 周):
1624
- - 仅支持 MongoDB(暂不跨数据库)
1625
- - 核心 API:withTransaction/startTransaction
1626
- - 高级功能后续增强
1627
- - **ROI 重新计算**:
1628
- - 开发成本:3.5 周(vs 原估算 15 周)
1629
- - 场景覆盖:45%(显性 15% + 潜在 30%)
1630
- - ROI:13% per week(vs 之前 1%)
1631
- - **实施时机**:
1632
- - v0.2.0: 质量提升(不实施事务)
1633
- - **v0.3.0**: 事务功能最小化实现(3.5 周)
1634
- - v1.0.0: 跨数据库事务增强
1635
- - STATUS.md 已更新:事务功能改为可实施方案
1636
-
1637
- - **事务与读取控制功能必要性分析**(2025-11-18)
1638
- - 深入分析 MongoDB 事务功能(startSession/withTransaction/commit/abort)
1639
- - 深入分析读取控制功能(readConcern/readPreference/causalConsistency)
1640
- - 分析方法:需求分析 + 竞品对比 + 成本收益分析
1641
- - 相关文件:
1642
- - `analysis-reports/2025-11-18-transactions-necessity-analysis.md` - 详细分析报告
1643
- - `analysis-reports/2025-11-18-transactions-decision-summary.md` - 决策摘要
1644
- - 初步结论(后被推翻):
1645
- - 事务功能: ❌ 不建议实施(成本高 15 周,收益低 15%)
1646
- - 重新评估后结论:
1647
- - 事务功能: ✅ 实施最小化方案(成本降至 3 周,创新点明确)
1648
-
1649
- - **全面项目分析报告**(2025-11-18)
1650
- - 三遍分析法完整报告:架构 → 质量 → 战略(30,000+ 字)
1651
- - 下一阶段行动计划:v0.2.0 质量提升与发布准备(4 周详细任务)
1652
- - 执行摘要:核心数据、优势劣势、关键建议
1653
- - 相关文件:
1654
- - `analysis-reports/2025-11-18-comprehensive-three-pass-analysis.md` - 完整分析报告
1655
- - `analysis-reports/2025-11-18-next-phase-action-plan.md` - 4 周行动计划
1656
- - `analysis-reports/2025-11-18-EXECUTIVE-SUMMARY.md` - 执行摘要
1657
- - 核心结论:
1658
- - 项目评级:A 级(88.6/100),生产就绪
1659
- - 核心功能完成度:93.8%(CRUD + 索引管理 100%)
1660
- - 核心优势:智能缓存(4-15 倍提升)+ 深度分页(O(1))
1661
- - 下一目标:v0.2.0 发布(测试 85%,文档 100%)
1662
-
1663
- ### Fixed
1664
- - **修复 mongodb-native-vs-extensions.md 表格格式**(2025-11-18)
1665
- - 修复"性能对比"表格缺少空行导致渲染错误
1666
- - 在表格前后添加必要的空行,确保 Markdown 正确渲染
1667
- - 修复了 2 处表格格式问题(深度分页性能对比表格)
1668
- - **修复 README.md 文档问题**(2025-11-18)
1669
- - 修正章节编号重复问题(两个"5. 多层缓存")
1670
- - 修正 insertOne/insertMany 的 API 调用示例(移除错误的嵌套 document 结构)
1671
- - 新增"10. 删除操作"示例章节(deleteOne/deleteMany/findOneAndDelete)
1672
- - 完善示例代码列表(新增 delete-operations、update、replace、indexes 等示例文件链接)
1673
- - 确认删除操作的自动缓存失效功能已完整实现
1674
- - **STATUS.md 状态修正**(2025-11-18)
1675
- - 修正了 Delete 方法(deleteOne, deleteMany, findOneAndDelete)的状态记录
1676
- - 这些方法实际已在 2025-11-13 完整实现,但 STATUS.md 错误标记为"计划中"
1677
- - 更新完成度统计:从 64.3% 提升到 68.6%
1678
- - 更新核心功能完成度:从 87.5% 提升到 93.8%
1679
- - 更新 CRUD 完成度:Delete 从"计划中"改为"已实现"
1680
- - 添加 bulkWrite 不推荐实现的说明和理由
1681
- - 添加下阶段实现计划章节(P1/P2/P3 优先级分类)
1682
- - 详细分析报告:`analysis-reports/2025-11-18-implementation-status-audit.md`
1683
-
1684
- ### Added
1685
- - **新增 incrementOne 便利方法**(2025-11-18)
1686
- - 新增 `incrementOne(filter, field, increment, options)` 方法 - 原子递增/递减字段值
1687
- - 支持单字段递增:`incrementOne(filter, 'count', 5)`
1688
- - 支持多字段同时操作:`incrementOne(filter, { count: 1, points: 10 })`
1689
- - returnDocument 选项(返回更新前/后的文档)
1690
- - 原子操作,并发安全,无竞态条件
1691
- - 26 个测试用例(基础功能/返回值/选项/参数验证/缓存/实际场景/边界/对比)
1692
- - 500+ 行完整文档,包含真实场景示例
1693
- - 简化 60% 的递增/递减代码
1694
- - 相关文件:
1695
- - `lib/mongodb/writes/increment-one.js` (190 行)
1696
- - `test/unit/features/incrementOne.test.js` (26 个测试)
1697
- - `docs/increment-one.md` (500+ 行)
1698
- - **新增 findByIds 便利方法**(2025-11-18)
1699
- - 新增 `findByIds(ids, options)` 方法 - 批量通过 _id 查询多个文档
1700
- - 自动 ObjectId 转换(字符串 → ObjectId,支持混合类型)
1701
- - 自动去重(重复 ID 只查询一次)
1702
- - preserveOrder 选项(保持 ids 数组的顺序)
1703
- - 支持所有 find 选项(projection, sort, cache, maxTimeMS, comment)
1704
- - 完整的参数验证和错误处理(无效 ID 检测)
1705
- - 27 个测试用例(基础功能/选项支持/参数验证/缓存/性能/实际场景/对比)
1706
- - 700+ 行完整文档,包含真实场景示例和性能对比
1707
- - 示例代码文件 `examples/findByIds.examples.js`(11 个场景示例)
1708
- - 简化 75% 的批量查询代码,1 次查询替代 N 次
1709
- - 相关文件:
1710
- - `lib/mongodb/queries/find-by-ids.js` (220 行)
1711
- - `test/unit/features/findByIds.test.js` (27 个测试)
1712
- - `docs/find-by-ids.md` (700+ 行)
1713
- - 更新文档:README.md, STATUS.md, docs/INDEX.md
1714
- - **新增 upsertOne 便利方法**(2025-11-18)
1715
- - 新增 `upsertOne(filter, update, options)` 方法 - 存在则更新,不存在则插入
1716
- - 自动包装 `$set`(无需手动添加,但仍支持所有更新操作符)
1717
- - 支持所有 MongoDB 更新操作符($inc, $push, $setOnInsert 等)
1718
- - 完整的参数验证和错误处理
1719
- - 自动缓存失效(操作成功后)
1720
- - 23 个测试用例(基础功能/返回值/选项/参数验证/缓存/实际场景/边界/对比)
1721
- - 700+ 行完整文档,包含真实场景示例和最佳实践
1722
- - 示例代码文件 `examples/upsertOne.examples.js`(8 个场景示例)
1723
- - 简化 67% 的 upsert 代码,语义更清晰
1724
- - 相关文件:
1725
- - `lib/mongodb/writes/upsert-one.js` (160 行)
1726
- - `test/unit/features/upsertOne.test.js` (23 个测试)
1727
- - `docs/upsert-one.md` (700+ 行)
1728
- - 更新文档:README.md, STATUS.md, docs/INDEX.md
1729
- - **完整的索引管理功能**(2025-11-17)
1730
- - `createIndex(keys, options)` - 创建单个索引,支持所有 MongoDB 索引选项
1731
- - `createIndexes(indexSpecs)` - 批量创建多个索引,提高部署效率
1732
- - `listIndexes()` - 列出集合的所有索引,支持索引审计和监控
1733
- - `dropIndex(indexName)` - 删除指定索引,禁止删除 _id 索引
1734
- - `dropIndexes()` - 删除所有索引(_id 除外),适用于索引重建
1735
- - **完整的索引选项支持**:
1736
- - unique(唯一索引)、sparse(稀疏索引)、expireAfterSeconds(TTL 索引)
1737
- - partialFilterExpression(部分索引)、collation(排序规则)、hidden(隐藏索引)
1738
- - wildcardProjection(通配符投影)、weights(文本索引权重)等所有选项
1739
- - **健壮的错误处理**:
1740
- - 灵活的错误码匹配(兼容不同 MongoDB 驱动版本)
1741
- - 友好的错误消息和完整的错误分类
1742
- - 统一的返回格式
1743
- - **完整的日志记录**:
1744
- - 操作开始/成功/失败日志
1745
- - 性能指标(duration)
1746
- - 详细的操作参数记录
1747
- - **完整的测试和文档**:
1748
- - 50+ 测试用例,100% 通过
1749
- - 10 个完整示例(examples/indexes.examples.js)
1750
- - 5 个详细 API 文档(docs/*.md)
1751
- - 完整的索引管理指南
1752
- - 实现了项目目标中的索引管理环节:explain() → **createIndex()** → 性能优化闭环
1753
-
1754
- ### Added
1755
- - **新增 findOneById 便利方法**(2025-11-18)
1756
- - 新增 `findOneById(id, options)` 方法 - 通过 _id 快速查询单个文档
1757
- - 自动处理字符串到 ObjectId 的转换(字符串 → ObjectId)
1758
- - 支持所有 findOne 选项(projection, cache, maxTimeMS, comment)
1759
- - 完整的参数验证和错误处理
1760
- - 21 个测试用例(基础功能/选项支持/缓存/参数验证/边界情况/性能对比/集成测试)
1761
- - 750+ 行完整文档,包含真实场景示例和最佳实践
1762
- - 示例代码文件 `examples/findOneById.examples.js`
1763
- - 简化 80% 的单文档查询代码,提升开发效率
1764
- - 相关文件:
1765
- - `lib/mongodb/queries/find-one-by-id.js` (165 行)
1766
- - `test/unit/features/findOneById.test.js` (21 个测试)
1767
- - `docs/find-one-by-id.md` (750+ 行)
1768
- - 更新文档:README.md, STATUS.md, docs/INDEX.md
1769
- - **更新 STATUS.md 记录阶段1完成**(2025-11-18)
1770
- - 更新文档完成度统计(新增"文档完成度: 100%"指标)
1771
- - 更新进度对比表(新增 2025-11-18 下午的文档补全成果)
1772
- - 标记 P1 任务为"已完成"状态(8 个任务全部完成)
1773
- - 更新功能优先级矩阵(CRUD 文档补全已完成)
1774
- - 新增"最近更新历史"章节(记录 2025-11-13 至 2025-11-18 的更新)
1775
- - 详细记录阶段1文档补全的所有成果(5 个新文档、78+ 示例、4 个工具函数)
1776
- - **新增 MongoDB 原生 vs monSQLize 扩展功能对比文档**(2025-11-18)
1777
- - 创建 `docs/mongodb-native-vs-extensions.md` 详细对比文档
1778
- - 10 大功能对比:缓存、分页、性能监控、跨库访问等
1779
- - 包含性能基准数据和使用建议
1780
- - 修正 README.md 中删除操作的错误状态(从"计划中"改为"已实现")
1781
- - **更新文档索引和导航**(2025-11-18)
1782
- - 更新 `docs/INDEX.md` 添加 4 个新文档的索引条目
1783
- - 在写入操作章节新增"删除操作"分类
1784
- - 更新 CRUD 分类,补充 delete 操作的详细链接
1785
- - 更新快速开始路径,包含完整的 CRUD 学习顺序
1786
- - 文档总数从 25 个增加到 29 个
1787
- - 更新 `README.md` 核心 API 列表
1788
- - 在写入操作表格中添加 deleteOne、deleteMany、findOneAndDelete 文档链接
1789
- - 将 insertOne、insertMany 链接从示例改为独立文档
1790
- - 所有文档链接已验证,确保可访问性
1791
- - **补充独立 API 文档**(2025-11-18)
1792
- - 新增 `docs/delete-one.md` - deleteOne 方法完整文档
1793
- - 新增 `docs/delete-many.md` - deleteMany 方法完整文档
1794
- - 新增 `docs/insert-one.md` - insertOne 方法完整文档
1795
- - 新增 `docs/insert-many.md` - insertMany 方法完整文档
1796
- - 每个文档包含:语法、参数、返回值、核心特性、常见场景、错误处理、性能优化、最佳实践
1797
- - 总计新增 4 个文档,约 **4000+ 行**详细文档
1798
- - 完成了审计报告中 P1 优先级任务(阶段1:文档补全)
1799
- - 相关报告:`analysis-reports/2025-11-18-implementation-status-audit.md`
1800
- - **MongoDB 驱动 API 使用检查完成**(2025-11-18)
1801
- - 完成代码库中所有直接使用 MongoDB 驱动 API 的检查
1802
- - 确认所有 `findOneAnd*` 方法都正确使用了 `result-handler` 模块
1803
- - 确认其他写操作方法(insertOne/updateOne/deleteOne 等)不受驱动版本影响
1804
- - 确认所有读操作和索引管理方法不受驱动版本影响
1805
- - 检查范围:13 个写操作文件、7 个读操作文件、5 个索引管理文件
1806
- - 检查结果:✅ 无问题发现,所有代码已正确处理驱动兼容性
1807
- - 详细报告:`analysis-reports/2025-11-18-driver-api-usage-check.md`
1808
- - **result-handler 工具模块单元测试**(2025-11-18)
1809
- - 新增 `test/unit/utils/result-handler.test.js` 独立单元测试文件
1810
- - 70 个测试用例,100% 通过率,全面覆盖 result-handler 的所有功能
1811
- - 测试覆盖:基础功能、边界情况、异常输入、真实使用场景、集成场景模拟
1812
- - 测试包含 `handleFindOneAndResult()` 和 `wasDocumentModified()` 两个核心函数
1813
- - 验证了 MongoDB 驱动 5.x 和 6.x 的兼容性处理逻辑
1814
- - 作为工具函数的使用文档和质量保证
1815
- - **MongoDB 驱动版本检测和警告机制**(2025-11-17)
1816
- - 在 `result-handler.js` 中添加了驱动版本自动检测功能
1817
- - 当检测到不支持的驱动版本(<6.x 或 >6.x)时自动输出警告日志
1818
- - 当遇到非预期的返回值格式时输出详细的诊断日志
1819
- - 帮助开发者及早发现驱动版本兼容性问题
1820
- - **MongoDB 驱动版本兼容性指南文档**(2025-11-17)
1821
- - 新增 `docs/mongodb-driver-compatibility.md` 完整兼容性指南
1822
- - 包含当前支持的驱动版本说明
1823
- - 包含驱动版本差异详解
1824
- - 包含未来驱动升级的标准流程和检查清单
1825
- - 包含开发者指南和 FAQ
1826
- - **新增 3 个删除方法**(2025-11-13)
1827
- - `deleteOne(filter, options)` - 删除单个匹配的文档
1828
- - `deleteMany(filter, options)` - 批量删除所有匹配的文档
1829
- - `findOneAndDelete(filter, options)` - 原子地查找并删除文档
1830
- - 所有方法支持 collation、hint、maxTimeMS、writeConcern、comment 等选项
1831
- - 自动缓存失效机制(删除成功后自动清理相关缓存)
1832
- - 慢查询日志记录(超过阈值时自动记录详细信息)
1833
- - 完整的参数验证和错误处理
1834
- - findOneAndDelete 支持 projection、sort 选项
1835
- - findOneAndDelete 支持 includeResultMetadata 选项(返回完整元数据)
1836
- - 完整的测试覆盖(60+ 个测试用例)
1837
- - 详细的 JSDoc 文档和代码示例
1838
- - 实现完整 CRUD 操作链(Create ✅ / Read ✅ / Update ✅ / Delete ✅)
1839
-
1840
- ### Changed
1841
- - **增强 result-handler.js 的诊断能力**(2025-11-17)
1842
- - `handleFindOneAndResult()` 函数现在接受可选的 `logger` 参数
1843
- - 自动检测 MongoDB 驱动版本并在首次调用时输出诊断信息
1844
- - 当返回值格式异常时输出详细的警告日志
1845
- - 帮助快速定位和诊断驱动兼容性问题
1846
- - **README 添加兼容性说明**(2025-11-17)
1847
- - 在"安装"章节添加了 MongoDB 驱动版本兼容性说明
1848
- - 提供兼容性指南和技术报告的链接
1849
- - **API 文档更新 - MongoDB 驱动版本说明**(2025-11-17)
1850
- - 在 `docs/find-one-and-update.md` 中添加了 MongoDB 驱动 6.x 的兼容性说明
1851
- - 在 `docs/find-one-and-replace.md` 中添加了驱动版本说明和完整返回值示例
1852
- - 新增 `docs/find-one-and-delete.md` 完整 API 文档
1853
- - 说明了驱动 5.x 和 6.x 之间的返回值格式差异
1854
- - 强调 monSQLize 已内部处理此差异,API 行为保持一致
1855
- - 新增技术分析报告:`analysis-reports/2025-11-17-mongodb-driver-6x-compatibility-FINAL.md`
1856
- - **文档结构优化**(2025-11-13)
1857
- - 将 `docs/api/` 子目录中的更新操作文档移到 `docs/` 根目录
1858
- - 重命名 `docs/api/README.md` 为 `docs/update-operations.md`
1859
- - 统一文档结构:所有 API 文档现在都在同一层级
1860
- - 改进:更容易查找和浏览文档,结构更清晰一致
1861
- - 移除 `docs/FAQ.md` - 项目尚在完善中,后期会更强大时再添加完整的 FAQ
1862
-
1863
- ### Fixed
1864
- - **findOneAndUpdate、findOneAndDelete、findOneAndReplace 方法修复**(2025-11-17)
1865
- - 修复了与 MongoDB 驱动 6.x 的 API 兼容性问题
1866
- - 问题:驱动 6.x 默认直接返回文档,而非 `{ value, ok, lastErrorObject }` 格式
1867
- - 解决方案:强制传递 `includeResultMetadata: true` 给驱动,确保获取完整元数据
1868
- - 修复了空值处理逻辑,避免空指针异常
1869
- - 修复了缓存失效判断逻辑,正确使用 `wasDocumentModified()` 函数
1870
- - 新增 `result-handler.js` 工具模块,统一处理三个方法的返回值
1871
- - 所有 44 个失败的测试用例现在全部通过
1872
- - **replaceOne 测试用例修复**(2025-11-17)
1873
- - 修复了"替换为空对象"测试:正确使用 `_id` 查询替换后的文档
1874
- - 调整测试预期以适应 MongoDB 驱动 6.x 的行为变化
1875
- - 说明:驱动 6.x 的 `replaceOne` 即使内容相同也会返回 `modifiedCount: 1`
1876
- - 这是 MongoDB 驱动的正常行为,因为驱动执行了写操作
1877
- - **insertMany 慢查询日志修复**(2025-11-13)
1878
- - 修复 `slowQueryMs` 设置为 `0` 时慢查询日志未被记录的 bug
1879
- - 根本原因:使用 `||` 运算符导致 `0` 被视为 falsy 值,回退到默认值 `1000`
1880
- - 解决方案:改用空值合并运算符 `??` 代替 `||`
1881
- - 影响:慢查询监控测试从 23/25 通过提升到 25/25 通过
1882
- - 影响范围:不影响核心功能,仅影响性能监控
1883
-
1884
- ### Added
1885
- - **P1 文档补充完成**(2025-11-13)
1886
- - 更新 README.md - 添加更新操作快速示例(updateOne/updateMany/findOneAndUpdate)
1887
- - 更新 README.md - 突出 CRUD 完整性(75% 完成)
1888
- - 更新 README.md - 添加 MongoDB 原生 vs monSQLize 功能对照表
1889
- - 更新 STATUS.md - CRUD 功能完成度矩阵(Create ✅ / Read ✅ / Update ✅ / Delete 🗺️)
1890
- - 更新 STATUS.md - Update 操作详情表格(5 个方法,172 个测试用例)
1891
- - 更新 STATUS.md - 近期路线图(Q4 2025 / Q1 2026)
1892
- - 完成度提升:文档完整性从 90% → 95%
1893
-
1894
- ### Added
1895
- - **新增 5 个更新方法**(2025-11-12)
1896
- - `updateOne(filter, update, options)` - 更新单个文档
1897
- - `updateMany(filter, update, options)` - 批量更新多个文档
1898
- - `replaceOne(filter, replacement, options)` - 完整替换单个文档
1899
- - `findOneAndUpdate(filter, update, options)` - 原子地查找并更新文档
1900
- - `findOneAndReplace(filter, replacement, options)` - 原子地查找并替换文档
1901
- - 所有方法支持 upsert、writeConcern、comment 等选项
1902
- - 自动缓存失效机制(修改成功后自动清理相关缓存)
1903
- - 慢查询日志记录(超过阈值时自动记录详细信息)
1904
- - 完整的参数验证和错误处理
1905
- - 支持 returnDocument 选项("before" 或 "after")
1906
- - 支持 includeResultMetadata 选项(返回完整元数据)
1907
- - 完整的测试覆盖(170+ 个测试用例)
1908
- - 详细的 JSDoc 文档和代码示例
1909
-
1910
- ### Fixed
1911
- - **修复 insertOne 测试失败**(2025-11-12)
1912
- - 修复慢查询日志测试的时序问题
1913
- - 改用 Promise + logger 拦截代替事件监听(项目尚未实现事件系统)
1914
- - 使用 -1ms 阈值代替 0ms 确保日志总是触发(解决快速操作可能 0ms 的问题)
1915
- - 所有 insertOne 测试现在全部通过(22/22)✅
1916
-
1917
- ### Added
1918
- - **新增测试文件提升覆盖率**(2025-11-12)
1919
- - 创建 `test/unit/infrastructure/redis-cache.test.js` - Redis 缓存适配器测试(基本操作、TTL、错误处理、序列化)
1920
- - 创建 `test/unit/common/shape-builders.test.js` - 形状构建器测试(元信息提取、pipeline 处理、游标处理、去敏验证)
1921
- - 创建 `test/unit/common/log.test.js` - 日志工具测试(慢查询检测、元数据结构、格式化、错误处理)
1922
- - 扩展 `test/unit/infrastructure/connection.test.js` - 连接错误处理测试(无效配置、网络超时、并发错误、健康检查)
1923
- - 目标:提升分支覆盖率从 63.88% 到 ≥70%(Profile 要求)
1924
-
1925
- - **项目全面分析报告**(2025-11-12)
1926
- - 创建 `analysis-reports/2025-11-12-comprehensive-analysis.md` - 项目健康度评估和改进建议
1927
- - 创建 `analysis-reports/2025-11-12-action-plan.md` - 详细的行动计划和优先级
1928
- - 分析内容包括:
1929
- - 代码质量分析(测试覆盖率、代码风格)
1930
- - 架构分析(设计模式、扩展性)
1931
- - 性能分析(缓存机制、查询优化)
1932
- - 文档质量分析(完整性、可用性)
1933
- - 依赖和安全分析
1934
- - 风险和挑战识别
1935
- - 关键发现:
1936
- - ✅ 整体质量良好(7.75/10)
1937
- - ⚠️ 分支覆盖率不达标(63.88% < 65%)
1938
- - ⚠️ 部分测试失败(insertOne 慢查询日志)
1939
- - ⚠️ Redis 缓存适配器未充分测试(1.49%)
1940
- - 行动计划:
1941
- - P0: 修复测试失败,提升覆盖率到 ≥70%
1942
- - P1: 补充文档(迁移指南、性能指南、架构文档)
1943
- - P2: 完善写操作(update/delete)
1944
- - P3: 索引管理、事务支持、PostgreSQL 适配器
1945
-
1946
- ### Changed
1947
- - **explain 示例和测试更新**(2025-11-12)
1948
- - `examples/explain.examples.js`:所有示例从旧版 `explain({ query, verbosity })` 改为原生风格 `find(filter, { explain })`
1949
- - 示例 1-5 全部更新为使用 options 参数的方式
1950
- - 保持与 MongoDB 原生 API 完全一致的调用风格
1951
-
1952
- - **explain 链式调用支持**(2025-11-12)
1953
- - ✨ 新增链式调用支持:
1954
- - `collection.find({ ... }).explain('executionStats')`
1955
- - `collection.aggregate([...]).explain('executionStats')`
1956
- - 完全兼容原生 MongoDB 的链式调用语法
1957
- - 通过在 Promise 上添加 explain() 方法实现
1958
- - 同时保留 options 参数方式:
1959
- - `find(filter, { explain: 'executionStats' })`
1960
- - `aggregate(pipeline, { explain: 'executionStats' })`
1961
- - ❌ 删除独立 explain 方法:`collection.explain({ query, verbosity })`(API 与原生不一致)
1962
- - 现在只支持两种方式:链式调用和 options 参数,都与原生 MongoDB 兼容
1963
- - 更新所有测试用例,使用新的 API
1964
-
1965
- - **explain 文档重构**(2025-11-12)
1966
- - 明确使用原生 MongoDB `Cursor.explain()` 方法
1967
- - 支持两种调用方式:链式调用和 options 参数
1968
- - 新增与原生 MongoDB 的对比:实现原理和使用示例
1969
- - 新增聚合管道的 explain 示例:管道分析、优化建议、阶段性能对比
1970
- - 新增常见问题章节:verbosity 选择、性能影响、执行计划解读、索引问题诊断、聚合管道优化
1971
-
1972
- - **distinct 文档重构**(2025-11-12) - 明确使用原生 MongoDB `Collection.distinct()` 方法
1973
- - 扩展 options 参数:新增 `session`(事务支持)、`comment`(查询注释)、`collation`(排序规则)等原生选项
1974
- - 新增使用模式:事务中的 distinct 查询(第 9 节)
1975
- - 新增使用建议章节:何时使用 distinct、性能考虑、缓存策略
1976
- - 优化常见问题:新增 Q1(monSQLize 与原生 MongoDB 的区别)、Q7(事务使用)
1977
- - 扩展最佳实践:从 7 条增加到 10 条,包含索引优化、缓存策略、事务使用等
1978
-
1979
- - **estimated-count 文档重构**(2025-11-12)
1980
- - 明确使用原生 MongoDB `estimatedDocumentCount()` 方法
1981
- - 扩展 options 参数:新增 `maxTimeMS`(超时控制)、`comment`(查询注释)等原生选项
1982
- - 新增性能对比章节:estimatedDocumentCount vs countDocuments vs count(性能差异对比)
1983
- - 新增使用建议章节:何时使用 estimatedDocumentCount、性能考虑
1984
- - 优化最佳实践:从简单列表扩展为详细说明,包含具体代码示例
1985
-
1986
- - **count 文档重构**(2025-11-12)
1987
- - 明确使用原生 MongoDB `countDocuments()` 方法
1988
- - 扩展 options 参数:新增 `skip`、`session`、`hint`、`comment` 等原生选项
1989
- - 新增使用模式:事务中的 count 查询、使用 hint 指定索引
1990
- - 优化最佳实践:添加具体代码示例和场景说明
1991
-
1992
- - **distinct 方法 API 重构**(2025-11-11)
1993
- - 方法签名变更:从 `distinct(field, options)` 改为 `distinct(field, query, options)`,将 query 参数独立出来
1994
- - 新增参数支持:`comment`(查询注释,用于日志和性能分析)
1995
- - 与 MongoDB 原生 API 保持一致:使用原生 `collection.distinct(field, query, options)` 方法
1996
- - 更新文档:`docs/distinct.md` - 反映新的 API 格式和参数说明
1997
- - 更新示例:`examples/distinct.examples.js` - 所有 10 个示例迁移到新 API
1998
- - ⚠️ **破坏性变更**:不兼容旧版本 `distinct('field', { query: {...} })` 格式,需修改为 `distinct('field', query, options)`
1999
-
2000
- - **count 方法 API 重构**(2025-11-11)
2001
- - 使用 MongoDB 原生推荐的 API:`countDocuments()` 和 `estimatedDocumentCount()`
2002
- - 方法签名变更:从 `count(options)` 改为 `count(query, options)`,将 query 参数独立出来
2003
- - 新增参数支持:`skip`、`limit`(用于分页统计和抽样统计)
2004
- - 性能优化:空查询自动使用 `estimatedDocumentCount()`(基于元数据,毫秒级)
2005
- - 更新文档:`docs/count.md` - 反映新的 API 格式和参数说明
2006
- - 更新示例:`examples/count.examples.js` - 所有示例迁移到新 API
2007
- - 创建迁移指南:`docs/count-migration-guide.md` - 帮助用户从旧版本迁移
2008
- - ⚠️ **破坏性变更**:不兼容旧版本 `count({ query: {...} })` 格式,需按迁移指南修改代码
2009
-
2010
- - **find 和 findOne 方法 API 重构**(2025-11-12)
2011
- - 方法签名变更:从 `find(options)` / `findOne(options)` 改为 `find(query, options)` / `findOne(query, options)`,将 query 参数独立出来
2012
- - 与 MongoDB 原生 API 保持一致:使用原生 `collection.find(query, options)` / `collection.findOne(query, options)` 方法
2013
- - 更新文档:
2014
- - `docs/find.md` - 反映新的 API 格式和参数说明(29 个代码示例全部更新)
2015
- - `docs/findOne.md` - 反映新的 API 格式和参数说明(15 个代码示例全部更新)
2016
- - `README.md` - 更新所有代码示例(13 个示例)
2017
- - 更新示例:
2018
- - `examples/find.examples.js` - 所有 10 个示例迁移到新 API
2019
- - `examples/findOne.examples.js` - 所有 7 个示例迁移到新 API
2020
- - 更新 TypeScript 定义:
2021
- - `index.d.ts` - 更新方法签名和接口定义
2022
- - 移除 `FindOptions.query` 字段
2023
- - 所有方法签名(find/findOne/count/distinct/stream/explain)改为两参数形式
2024
- - ⚠️ **破坏性变更**:不兼容旧版本 `find({ query: {...} })` 格式,需修改为 `find(query, options)`
2025
-
2026
- ### 新增
2027
- - **insertOne 和 insertMany 写操作文档补充**(2025-11-10)
2028
- - README.md:添加"写入操作"表格和详细使用示例(第 8 节)
2029
- - index.d.ts:添加 TypeScript 类型声明(InsertOneOptions、InsertOneResult、InsertManyOptions、InsertManyResult、WriteConcern)
2030
- - docs/write-operations.md:创建详细文档(全面的 API 说明、使用示例、性能对比、最佳实践、常见问题)
2031
- - 完整遵循 Guidelines v2.md 第 3.1 章"四要素"(Code ✅、Tests ✅、Examples ✅、Documentation ✅)
2032
-
2033
- - **insertOne 和 insertMany 写操作支持**(2025-11-10)
2034
- - 实现 `insertOne(document, options)` - 单文档插入操作
2035
- - 支持参数:writeConcern, comment, bypassDocumentValidation
2036
- - 返回:`{ acknowledged, insertedId }`
2037
- - 自动缓存失效:插入成功后自动失效该集合的所有查询缓存
2038
- - 慢查询日志:插入耗时超过 slowQueryMs 时记录
2039
- - 错误处理:检测重复键错误(E11000)并转换为标准错误码 `DUPLICATE_KEY`
2040
- - 实现 `insertMany(documents, options)` - 批量文档插入操作
2041
- - 支持参数:ordered(默认 true), writeConcern, comment, bypassDocumentValidation
2042
- - 返回:`{ acknowledged, insertedCount, insertedIds }`
2043
- - 批量插入性能优化:500 文档批量插入比 500 次单次插入快约 50 倍
2044
- - 有序模式(ordered: true):遇到错误停止,已插入文档不会回滚
2045
- - 无序模式(ordered: false):遇到错误继续插入其他文档
2046
- - 自动缓存失效:批量插入成功后自动失效该集合的所有查询缓存
2047
- - 创建文件:`lib/mongodb/writes/insert-one.js`(136 行)、`lib/mongodb/writes/insert-many.js`(184 行)
2048
- - 测试覆盖:insertOne 测试 17 个用例,insertMany 测试 21 个用例(包括性能对比测试)
2049
- - 示例文件:`examples/insertOne.examples.js`、`examples/insertMany.examples.js`
2050
- - 错误码支持:新增 `DUPLICATE_KEY` 错误码(用于重复键检测)
2051
- - 测试运行器增强:支持 `beforeEach/afterEach` 钩子,支持 `this.timeout()` 方法
2052
-
2053
- - **readPreference 副本集读偏好支持**(2025-11-07)
2054
- - 在连接配置中添加 `readPreference` 选项,支持副本集读写分离场景
2055
- - 支持 5 种读偏好模式:`primary`(默认)、`primaryPreferred`、`secondary`、`secondaryPreferred`、`nearest`
2056
- - 适用场景:副本集部署、降低主节点负载、全球分布式部署
2057
- - TypeScript 类型声明已同步更新(`BaseOptions.readPreference`)
2058
- - 示例文件:`examples/readPreference.examples.js`(7 个使用场景)
2059
- - 测试覆盖:mongodb-connect.test.js 新增 readPreference 配置透传测试
2060
- - ⚠️ 注意:仅全局配置(连接级别),MongoDB 专属特性,读从节点可能有复制延迟
2061
-
2062
- - **comment 参数支持**(2025-11-07)
2063
- - 为 `find`、`findOne`、`count` 方法添加 `comment` 参数,用于生产环境日志跟踪
2064
- - 支持在 MongoDB 日志中标识查询来源、业务场景、用户/会话/traceId 等关键信息
2065
- - TypeScript 类型声明已同步更新(`FindOptions`、`CountOptions`)
2066
- - 示例文件:`examples/comment-parameter.examples.js`(5 个使用场景)
2067
- - 适用场景:生产环境运维、慢查询诊断、分布式追踪、A/B 测试分析
2068
- - 参考:MongoDB 官方文档 [Database Profiler](https://www.mongodb.com/docs/manual/reference/command/profile/)
2069
-
2070
- - **Bookmark 维护 API**(2025-11-06)
2071
- - 新增 `prewarmBookmarks(keyDims, pages)` - 预热指定页面的 bookmark 缓存
2072
- - 新增 `listBookmarks(keyDims?)` - 列出已缓存的 bookmark,支持按查询维度过滤
2073
- - 新增 `clearBookmarks(keyDims?)` - 清除 bookmark 缓存,支持精确控制
2074
- - 创建 `lib/mongodb/management/bookmark-ops.js` 模块(167 行)
2075
- - 完整文档:`docs/bookmarks.md`
2076
- - 示例文件:`examples/bookmarks.examples.js`
2077
- - 测试覆盖:16/16 测试通过
2078
-
2079
- ### 改进
2080
- - **完整模块化重构**(2025-11-06)
2081
- - **主文件精简**:`lib/mongodb/index.js` 从 843 行精简至 235 行(减少 72%)
2082
- - **模块化架构**:
2083
- - 创建 7 个查询模块:find.js, find-one.js, count.js, aggregate.js, distinct.js, explain.js, find-page.js
2084
- - 创建 4 个管理模块:namespace-ops.js, collection-ops.js, cache-ops.js, bookmark-ops.js
2085
- - 统一导出:queries/index.js, management/index.js
2086
- - **工厂函数模式**:所有模块使用 `createXXX()` 工厂函数,支持上下文注入和闭包封装
2087
- - **循环依赖解决**:通过正确的创建顺序(findPageOps → accessor → bookmarkOps)解决循环依赖
2088
- - **动态缓存获取**:使用 `getCache()` 回调支持测试时动态替换 cache
2089
- - **代码质量**:所有测试通过(12/12 测试套件,308 个测试),无性能回归
2090
- - **文档完整**:所有 API 有对应的文档和示例
2091
-
2092
- - **代码质量优化**(2025-11-06)
2093
- - 清理 `lib/mongodb/index.js` 中 7 个未使用的模块导入(减少 36.8% 的导入)
2094
- - 删除:reverseSort, pickAnchor, buildPagePipelineA, decodeCursor, makePageResult, validateLimitAfterBefore, assertCursorSortCompatible
2095
- - 原因:这些模块已被 `find-page.js` 内部使用,无需在主文件中导入
2096
- - 添加区域注释:在 collection() 方法内添加 7 个功能区域标记(命名空间、集合管理、缓存管理、查询方法、聚合统计、查询分析、分页、Bookmark)
2097
- - 优化代码导航:支持 VS Code "Go to Symbol" 快速跳转
2098
- - 创建模块化基础设施:
2099
- - 新建 `lib/mongodb/queries/` 和 `lib/mongodb/management/` 目录
2100
- - 完成 2 个示例模块:`management/namespace.js`, `management/collection-ops.js`
2101
- - 验证脚本:`verify-refactoring.js`(模块化方案可行性验证通过)
2102
- - 完整重构分析:`guidelines/analysis-reports/2025-11-06-mongodb-adapter-refactoring-analysis.md`
2103
- - 所有测试通过(308/308),无性能回归
2104
-
2105
- ### 修复
2106
- - **缓存文档澄清**(2025-11-06)
2107
- - 修正 `docs/cache.md` 中关于"自动失效"的误导性描述
2108
- - 明确说明 monSQLize 是只读 API,不支持 insert/update/delete 操作
2109
- - 澄清缓存失效方式:仅通过 `invalidate()` 方法手动清理
2110
- - 移除所有对不存在的写操作方法的引用
2111
- - 更新"常见问题"章节,准确描述手动缓存清理流程
2112
-
2113
- ### 改进
2114
- - **高级查询选项评估完成**(2025-11-06)
2115
- - 完成对 11 个 MongoDB 高级选项的全面评估(noCursorTimeout/tailable/max/min/returnKey/allowPartialResults/readPreference/readPreferenceTags/readConcern/comment/let)
2116
- - 评估维度:必要性、实施难度、跨数据库兼容性、风险
2117
- - 确认当前已支持:hint, collation, batchSize, comment (aggregate)
2118
- - 确定实施优先级:
2119
- - P1(推荐实施): comment 扩展到 find/findOne/count
2120
- - P2(可选实施): readPreference (全局配置), max/min, readConcern, let
2121
- - P3(不实施): noCursorTimeout, tailable, returnKey, allowPartialResults, readPreferenceTags
2122
- - 详细分析报告:`guidelines/analysis-reports/2025-11-06-advanced-query-options-evaluation.md`
2123
- - 更新 STATUS.md 反映评估结论
2124
-
2125
- - **项目规范文档优化**(2025-11-06)
2126
- - 在 `guidelines/profiles/monSQLize.md` 新增"MongoDB 连接模式"章节
2127
- - 详细说明测试环境的推荐连接方式:`config: { useMemoryServer: true }`
2128
- - 解释自动 Memory Server 的优势(自动管理生命周期、无需手动清理)
2129
- - 说明不推荐手动管理 MongoMemoryServer 的原因
2130
- - 明确如何访问原生 MongoDB 实例:`msq._adapter.db`(非 `msq.db`)
2131
- - 更新测试模板,展示完整的 useMemoryServer 使用示例
2132
- - 添加检查清单,防止 AI 助手再次犯错
2133
-
2134
- ### 新增
2135
- - **缓存失效测试**(2025-11-06)
2136
- - 新增 `test/unit/features/invalidate.test.js` 测试套件
2137
- - 10 个测试用例覆盖 `invalidate()` 方法的所有场景:
2138
- - 基本功能:清除指定集合缓存、多集合隔离、多操作类型缓存
2139
- - 指定操作类型清除:按 `op` 参数清除特定操作缓存
2140
- - 边界情况:空缓存、缓存禁用场景、连续调用
2141
- - 实际场景:批量清除多个集合缓存
2142
- - 所有测试通过,覆盖率 100%
2143
-
2144
- - **Redis 缓存适配器**(2025-11-06)
2145
- - 新增内置 `createRedisCacheAdapter()` 工具函数,轻松启用 Redis 多层缓存
2146
- - 支持两种使用方式:
2147
- - 传入 Redis URL 字符串(自动创建 ioredis 实例)
2148
- - 传入已创建的 ioredis 实例(复用现有连接)
2149
- - 实现完整的 CacheLike 接口(10 个方法):
2150
- - 基础操作:get/set/del/exists
2151
- - 批量操作:getMany/setMany/delMany
2152
- - 模式操作:delPattern(使用 SCAN 避免阻塞)
2153
- - 全局操作:clear/keys(使用 SCAN 避免阻塞)
2154
- - 优化特性:
2155
- - 使用 `psetex` 支持毫秒级 TTL
2156
- - 使用 `SCAN` 代替 `KEYS` 避免生产环境阻塞
2157
- - 自动 JSON 序列化/反序列化
2158
- - 错误容错(解析失败返回 undefined)
2159
- - 使用示例:
2160
- ```javascript
2161
- const msq = new MonSQLize({
2162
- cache: {
2163
- multiLevel: true,
2164
- remote: MonSQLize.createRedisCacheAdapter('redis://localhost:6379/0')
2165
- }
2166
- });
2167
- ```
2168
- - 可选依赖:ioredis(peerDependencies,按需安装)
2169
- - 示例文件:`examples/multi-level-cache.examples.js`(3 个完整示例)
2170
- - 详细文档:`docs/cache.md#多层缓存`
2171
-
2172
- - **[P2.2] Bookmark 维护 APIs**(2025-11-06)
2173
- - 新增 3 个 bookmark 管理 API,用于运维调试和性能优化:
2174
- - `prewarmBookmarks(keyDims, pages)`:预热指定页面的 bookmark 缓存
2175
- - `listBookmarks(keyDims?)`:列出已缓存的 bookmark(支持按查询过滤或查看全部)
2176
- - `clearBookmarks(keyDims?)`:清除指定查询或全部 bookmark 缓存
2177
- - 核心特性:
2178
- - 智能 Hash 匹配:自动应用 `ensureStableSort` 规范化,确保与 findPage 使用相同的缓存键
2179
- - 精确控制:支持按 keyDims 精确管理特定查询的 bookmark
2180
- - 全局操作:不传 keyDims 可操作所有 bookmark(适用于全局重置)
2181
- - 失败检测:prewarmBookmarks 自动检测超出范围的页面并标记为 `failed`
2182
- - 缓存可用性检查:所有 API 在缓存不可用时抛出 `CACHE_UNAVAILABLE` 错误
2183
- - 使用场景:
2184
- - 系统启动时预热热点页面(减少首次查询延迟)
2185
- - 运维监控查看已缓存的页面分布
2186
- - 数据变更后清除相关缓存确保一致性
2187
- - 内存管理:按需清理缓存释放资源
2188
- - 测试:16 个测试用例,覆盖所有参数、边界情况和多查询隔离
2189
- - 示例:`examples/bookmarks.examples.js` 包含 5 个完整工作流
2190
- - 类型声明:`BookmarkKeyDims`、`PrewarmBookmarksResult`、`ListBookmarksResult`、`ClearBookmarksResult` 完整类型支持
2191
-
2192
- - **[P2.1] explain 诊断 API**(2025-11-06)
2193
- - 新增 `explain(options)` 方法,用于查询执行计划分析和性能诊断
2194
- - 支持 3 种 verbosity 模式:
2195
- - `queryPlanner`(默认):返回查询优化器选择的执行计划(不执行查询)
2196
- - `executionStats`:实际执行查询并返回详细统计信息(扫描文档数、耗时等)
2197
- - `allPlansExecution`:返回所有候选执行计划及其试执行结果
2198
- - 支持参数:query, projection, sort, limit, skip, maxTimeMS, hint, collation
2199
- - 特性:
2200
- - 禁用缓存(诊断专用,不影响正常查询性能)
2201
- - 集成慢查询日志(执行耗时 > slowQueryMs 阈值)
2202
- - 错误处理:无效 verbosity 抛出 INVALID_EXPLAIN_VERBOSITY
2203
- - 使用场景:
2204
- - 验证索引是否被正确使用
2205
- - 诊断慢查询根本原因
2206
- - 对比不同查询策略的性能
2207
- - 分析复杂查询的执行计划
2208
- - 测试:15 个测试用例覆盖所有参数和边界情况
2209
- - 示例:`examples/explain.examples.js` 包含 5 个实用场景
2210
- - 类型声明:`ExplainOptions` 接口完整类型支持
2211
-
2212
- - **[P1.3] 性能基准测试框架**(2025-11-06)
2213
- - 创建 `test/benchmark/run-benchmarks.js` 统一的基准测试运行器
2214
- - 使用 benchmark.js 测试所有核心 API 性能
2215
- - 测试覆盖:findOne/find/count/findPage/aggregate/distinct(13个测试场景)
2216
- - 记录性能基线到 `test/benchmark/BASELINE.md`
2217
- - 关键发现:
2218
- - 缓存效果显著:findOne 带缓存 14,763 ops/sec vs 简单查询 3,361 ops/sec(4.4倍提升)
2219
- - count 缓存提升:14,723 ops/sec vs 条件查询 994 ops/sec(14.8倍提升)
2220
- - estimatedDocumentCount 比 countDocuments 快 6.7倍
2221
- - 排序代价:带排序 393 ops/sec vs 无排序 3,706 ops/sec(9.4倍下降)
2222
- - 添加 npm run benchmark 命令
2223
-
2224
- - **[P1.2] 示例验证已加入 CI**(2025-11-06)
2225
- - 创建 `scripts/verify-examples.js` 自动验证所有示例可运行
2226
- - 所有示例改为使用 Memory Server(`useMemoryServer: true`)
2227
- - CI workflow 添加示例验证步骤(Node 20.x + ubuntu-latest)
2228
- - 确保文档中的示例与实际代码保持一致
2229
-
2230
- - **[P1] 分支覆盖率大幅提升**:从 61.51% 提升至 65.9%(+4.39%)
2231
- - **Phase 1: cache.js**(2025-11-05)
2232
- - 新增 `test/unit/infrastructure/cache.test.js` Suite 7-9(13 测试用例)
2233
- - 测试内容:BSON 序列化、循环引用处理、命名空间模式
2234
- - 覆盖率:51.11% → 62.96% (+11.85%)
2235
- - **Phase 2: index.js**(2025-11-05)
2236
- - 新增 `test/unit/infrastructure/index.test.js` Suite 1-7(15+ 测试用例)
2237
- - 测试内容:构造函数边界、deepMerge、helper 方法(getCache/getDefaults/close/health/on/off)
2238
- - 覆盖率:44.44% → 75% branches (+30.56%), 50% → 100% functions (+50%)
2239
- - **Phase 3: mongodb/connect.js**(2025-11-05)
2240
- - 新增 `test/unit/infrastructure/mongodb-connect.test.js` Suite 1-5(6 测试用例)
2241
- - 测试内容:stopMemoryServer 边界、closeMongo 参数、connectMongo 异常、close 异常处理
2242
- - 覆盖率:37.5% → 67.86% branches (+30.36%), 80% → 100% functions (+20%)
2243
- - 总体:新增 40+ 测试用例,分支覆盖率 61.51% → 65.9%,超额完成 P1.1 目标(65%)
2244
-
2245
- - **[P0] Logger.js 测试覆盖率大幅提升**:从 37.28% 提升至 93.22%
2246
- - 新增 `test/unit/infrastructure/logger.test.js` Suite 6-9(20+测试用例)
2247
- - 测试内容:withTraceId 嵌套与异步传播、带时间戳日志、边界情况处理、所有日志级别
2248
- - 覆盖率提升:语句 93.22% (+55.94%), 分支 76.92% (+46.92%), 函数 100% (+40%), 行 94.54% (+56.54%)
2249
- - 未覆盖行仅 3 行(29, 141, 200),均为极边缘异常处理分支
2250
- - 整体项目覆盖率:语句 77.04% (+3.32%), 函数 81.42%, 行 79.52%
2251
-
2252
- ### 改进
2253
- - **[P0] TypeScript 类型声明完善**:验证所有 API 均有完整类型定义
2254
- - 确认 findOne/find/count/aggregate/distinct/stream/findPage 所有方法有完整类型声明
2255
- - 所有方法支持 meta 参数重载(ResultWithMeta<T>)
2256
- - StreamOptions/AggregateOptions/DistinctOptions 接口完整
2257
- - PageResult<T> 支持 totals 和 meta 字段
2258
- - 类型覆盖率 100%
2259
-
2260
- - **[P0] CI/CD 配置完善**:验证测试矩阵和覆盖率上传配置
2261
- - 测试矩阵:Node.js 18.x/20.x × Ubuntu/Windows(4 种组合)
2262
- - 覆盖率上传:Codecov (lcov.info, flags: unittests)
2263
- - ESLint 检查:已启用(continue-on-error: true)
2264
- - 依赖缓存:npm cache 优化
2265
- - CI 健康度:⭐⭐⭐⭐⭐ 5/5
2266
-
2267
- - **[P0] 完整测试套件验证**:所有测试通过,无回归问题
2268
- - 测试套件:9/9 通过(278+ 测试用例)
2269
- - 总耗时:4.79s(快速反馈)
2270
- - 新增 Logger 测试套件全部通过
2271
- - 无回归问题
2272
-
2273
- - **[测试] 集成 MongoDB Memory Server(配置驱动方案)**:通过 `config.useMemoryServer` 控制是否使用内存数据库
2274
- - 在 `lib/mongodb/connect.js` 中添加内存数据库支持
2275
- - 通过 `config: { useMemoryServer: true }` 显式启用
2276
- - 单例模式:所有测试共享同一个内存服务器实例,性能优异
2277
- - 测试文件统一添加配置参数,逻辑清晰明确
2278
- - 优势:**配置驱动、显式明确、单例优化、零生产风险**
2279
- - 测试验证:所有测试套件全部通过,性能优秀 ✅
2280
-
2281
- - **[测试] 改进缓存功能测试**:通过检查缓存统计信息验证缓存是否真的生效
2282
- - 移除不稳定的时间比较断言(在内存数据库环境下不可靠)
2283
- - 使用 `msq.cache.getStats()` 检查缓存命中次数
2284
- - 验证 `hits` 统计是否增加,直接证明缓存命中
2285
- - 同时保留结果一致性验证
2286
- - **添加详细日志输出**:打印前后命中次数、未命中次数、缓存命中率
2287
- - **使用 resetStats() 隔离测试**:确保每个测试独立,不受其他测试影响
2288
- - 测试输出更加直观易懂 ✅
2289
-
2290
- ### 修复
2291
- - **[错误码] 添加 STREAM_NO_EXPLAIN 错误码**:修复 `findPage` 方法在流式模式下使用 `explain` 参数时的错误码不一致问题,从通用的 `VALIDATION_ERROR` 改为更具体的 `STREAM_NO_EXPLAIN`,提供更清晰的错误信息。
2292
- - **[测试] 修复 all 模式测试运行器**:修复 `test/run-tests.js` 中 `all` 模式一次性加载所有测试导致的并发初始化问题,改为顺序执行各个测试套件,避免 MongoDB 连接池耗尽和索引创建冲突。
2293
- - **[测试] 移除导致超时的连接错误测试**:移除 `connection.test.js` 中使用无效主机的连接测试,该测试会导致长时间 DNS 查询超时,阻塞整个测试套件。建议后续使用 mock 或快速失败策略补充连接错误测试。
2294
-
2295
- ### 新增
2296
- - **[P0] 建立 CI/CD 流程**:完整的自动化测试和发布流程
2297
- - 创建 `.github/workflows/test.yml` 测试工作流
2298
- - 创建 `.github/workflows/release.yml` 发布工作流
2299
- - 支持 Node.js 18.x, 20.x,Ubuntu 和 Windows
2300
- - 自动运行测试、覆盖率检查和 Lint
2301
- - 基于 Git 标签自动发布 GitHub Release
2302
- - **[P0] 添加代码覆盖率**:建立质量门禁
2303
- - 集成 nyc 覆盖率工具
2304
- - 设置覆盖率门禁(Lines≥70%, Statements≥70%, Functions≥70%, Branches≥65%)
2305
- - 生成 text、lcov 和 html 三种格式报告
2306
- - 支持上传到 Codecov
2307
- - **[P0] 配置 ESLint**:统一代码风格
2308
- - 创建 `.eslintrc.js` 配置文件
2309
- - 4 空格缩进,Unix 换行符,单引号,强制分号
2310
- - 推荐使用 const,警告未使用变量
2311
- - 添加 `npm run lint` 和 `npm run lint:fix` 脚本
2312
- - **[P0] 性能基准测试**:建立性能追踪体系
2313
- - 创建 `test/benchmark/run-benchmarks.js` 基准测试运行器
2314
- - 测试 findOne、find、findPage、count 和缓存效率
2315
- - 输出 ops/sec、ms/op 和 RME 性能指标
2316
- - 添加 `npm run benchmark` 脚本
2317
- - 创建基准测试文档和性能目标
2318
- - **[P0] 补充工具函数测试**:提升测试覆盖率
2319
- - 创建 `test/unit/utils/cursor.test.js` - 游标编解码测试(21 用例)
2320
- - 创建 `test/unit/utils/normalize.test.js` - 参数标准化测试(26 用例)
2321
- - 创建 `test/unit/utils/page-result.test.js` - 分页结果测试(14 用例)
2322
- - 创建 `test/unit/utils/shape-builders.test.js` - 查询形状测试(占位)
2323
- - 更新 `test/run-tests.js` 支持 utils 子目录
2324
- - 新增 65+ 个测试用例,覆盖核心工具函数
2325
-
2326
- ### 新增
2327
- - **[P1] findPage 测试用例补充**:基于详细分析报告补充缺失的测试场景
2328
- - 创建 `analysis-reports/2025-11-04-findPage-test-analysis.md` 详细分析报告
2329
- - 创建 `test/unit/features/findPage-supplement.test.js` 补充测试文件
2330
- - 创建 `analysis-reports/2025-11-04-findPage-supplement-test-success-report.md` 执行报告
2331
- - 创建 `scripts/verify/compliance/verify-findpage-supplement-tests.js` 静态验证脚本
2332
- - P1.1: totals 模式完整性测试(none/approx/失败降级/缓存失效)- 4/4 通过 ✅
2333
- - P1.2: meta 子步骤耗时测试(基础meta/子步骤/上下文信息)- 2/2 通过 ✅
2334
- - P1.3: 缓存键冲突测试(不同查询条件/不同排序/相同查询/不同limit)- 4/4 通过 ✅
2335
- - P2.1: 并发安全测试(并发查询不同页/缓存并发写入/并发流式查询)- 3/3 通过 ✅
2336
- - P2.2: 游标编解码测试(可逆性/格式验证/篡改检测/排序一致性)- 4/4 通过 ✅
2337
- - P3.1: 边缘场景测试(空集合/无匹配/limit大于总数/单条数据/复杂查询)- 5/5 通过 ✅
2338
- - **所有 23 个测试用例全部通过(100%通过率)✅**
2339
- - 测试执行时间: 0.25 秒(优化后)
2340
- - 核心发现:缓存性能优秀(1ms→0ms)、并发安全完美、容错处理完善
2341
-
2342
- ### 修复
2343
- - **[P1] totals.mode='approx' 实现**:补充近似统计功能
2344
- - 空查询使用 `estimatedDocumentCount`(快速近似)
2345
- - 有查询条件使用 `countDocuments`(精确统计)
2346
- - 支持缓存和失败降级
2347
- - 返回 `approx: true` 标记
2348
- - **[P1] 游标排序一致性验证**:增强游标安全性
2349
- - 修改 `assertCursorSortCompatible` 抛出 `CURSOR_SORT_MISMATCH` 错误码
2350
- - 验证游标中的排序与当前查询排序完全一致
2351
- - 防止使用错误排序的游标导致分页结果错误
2352
- - 错误信息包含详细的排序对比
2353
- - **[P1] 缓存系统测试**:补充缺失的基础设施测试
2354
- - 创建 `test/unit/infrastructure/cache.test.js` 缓存系统完整测试
2355
- - 测试内容:set/get/del、TTL过期、LRU淘汰、统计功能、批量操作、exists检查
2356
- - 覆盖 6 大功能模块,10+ 测试用例
2357
- - 所有测试通过 ✅
2358
- - **[规范] 测试分类结构优化**:按照第21章标准完成单元测试内部分类
2359
- - 创建 `test/unit/features/` 存放功能性测试(6个业务功能测试)
2360
- - 创建 `test/unit/infrastructure/` 存放基础设施测试(4个底层支撑测试)
2361
- - 创建 `test/unit/utils/` 存放工具函数测试(待添加)
2362
- - 更新所有测试文件路径 (`../../lib` → `../../../lib`)
2363
- - 更新 `test/run-tests.js` 支持分类结构
2364
- - 更新 `test/README.md` 说明测试分类标准
2365
- - 符合 [第21章 测试分类标准](../guidelines/guidelines/v2.md#21-验证与测试策略完整流程)
2366
- - **[规范] scripts/ 目录结构调整**:按照第22章标准创建验证脚本目录
2367
- - 创建 `scripts/verify/compliance/` 目录存放合规性验证脚本(一次性执行)
2368
- - 创建 `scripts/verify/docs/` 目录存放文档验证脚本(CI执行)
2369
- - 移动 `test/verify-p0.js` → `scripts/verify/compliance/verify-p0-improvements.js`
2370
- - 创建 `scripts/README.md` 完整说明文档
2371
- - 创建 `scripts/verify/compliance/README.md` 合规性验证指南
2372
- - 创建 `scripts/verify/docs/README.md` 文档验证指南
2373
- - 符合 [第22章 验证脚本与工具目录规范](../guidelines/guidelines/v2.md#22-验证脚本与工具目录规范)
2374
- - **[P0] 测试目录结构迁移**:按照第21章标准完成测试目录重组
2375
- - 创建 `test/unit/`, `test/integration/`, `test/e2e/` 标准目录结构
2376
- - 将所有单元测试迁移到 `test/unit/` 目录(10个测试文件)
2377
- - 更新 `test/run-tests.js` 支持子目录结构
2378
- - 更新所有测试文件中的相对路径(`../lib` → `../../lib`)
2379
- - 更新 `test/verify-p0.js` 验证脚本路径
2380
- - 符合 [第21章 验证与测试策略](../guidelines/guidelines/v2.md#21-验证与测试策略完整流程)
2381
- - **[P0] 标准目录结构规范**:按照通用规范调整项目目录结构
2382
- - 创建 `analysis-reports/` 目录存放项目分析报告(P0-improvements-report.md 已移入)
2383
- - 创建 `bug-analysis/` 目录用于存放 Bug 分析报告(永久保留)
2384
- - 创建 `test/README.md` 详细说明测试目录结构和规范
2385
- - 目录结构符合 [第19.2章 项目标准目录结构规范](../guidelines/guidelines/v2.md#192-项目标准目录结构规范)
2386
- - **注意**: test/ 目录结构应遵循第21章标准(unit/integration/e2e),当前为过渡状态
2387
-
2388
- ### 变更
2389
- - **[规范] 修正目录结构定义重复**:
2390
- - 移除 19.2 章节中关于 test/ 的详细定义(与第21章重复)
2391
- - test/ 目录规范统一引用第21章《验证与测试策略完整流程》
2392
- - 简化 docs/ 和 examples/ 目录说明,避免过度详细
2393
- - 19.2 章节聚焦于"整体项目目录结构",不深入单个目录内部结构
2394
- - **[P0] 统一错误码系统**:新增 `lib/errors.js` 集中管理所有错误类型
2395
- - 定义标准错误码常量(`ErrorCodes`)
2396
- - 提供错误创建工厂函数(`createError`, `createValidationError`, `createCursorError` 等)
2397
- - 统一错误对象结构(code, message, details, cause)
2398
- - 更新所有模块使用统一错误码(`validation.js`, `find-page.js`)
2399
- - **[P0] 增强日志系统**:升级 `lib/logger.js` 支持现代日志特性
2400
- - 新增 traceId 支持(基于 AsyncLocalStorage,用于分布式追踪)
2401
- - 新增结构化日志输出(JSON 格式,便于日志聚合和分析)
2402
- - 新增上下文信息传递(数据库、集合、操作等元数据)
2403
- - 提供 `withTraceId()` 和 `getTraceId()` API
2404
- - 向后兼容原有 API
2405
- - **[P0] 常量配置系统**:新增 `lib/constants.js` 统一管理配置常量
2406
- - 缓存相关常量(默认大小、超时、去重窗口)
2407
- - 查询相关常量(慢查询阈值、默认 limit)
2408
- - 分页相关常量(书签密度、最大 hops)
2409
- - 流式查询常量(批次大小)
2410
- - 连接、命名空间、日志相关常量
2411
- - 消除代码中的魔法数字
2412
-
2413
- ### 变更
2414
- - **代码质量提升**:重构核心模块以提高可维护性
2415
- - `validation.js` 使用统一错误创建函数
2416
- - `find-page.js` 使用常量配置替代硬编码值
2417
- - 改善错误消息的可操作性
2418
-
2419
- ### 修复
2420
- - **并发连接问题**:修复高并发调用 `connect()` 时创建多个连接的问题
2421
- - 在 `lib/index.js` 和 `lib/mongodb/index.js` 两层添加连接锁(`_connecting`)
2422
- - 并发请求现在会等待同一个连接 Promise,确保只建立一个连接
2423
- - 添加完整的测试用例验证 10 个并发请求共享同一连接
2424
- - **输入验证缺失**:为 `collection()` 方法添加参数校验
2425
- - 集合名必须是非空字符串,否则抛出 `INVALID_COLLECTION_NAME` 错误
2426
- - 数据库名(如果提供)必须是非空字符串,否则抛出 `INVALID_DATABASE_NAME` 错误
2427
- - 添加友好的错误消息,包含参数要求说明
2428
- - 添加完整的测试用例覆盖空字符串、null、纯空格、非字符串等边界情况
2429
- - **内存泄漏**:修复 `close()` 方法未清理缓存的问题
2430
- - 清理 `_iidCache`(实例 ID 缓存),防止多次连接-关闭循环累积内存
2431
- - 清理 `_connecting` 锁,避免连接状态残留
2432
- - 添加完整的测试用例验证多次连接-关闭循环无内存泄漏
2433
-
2434
- ### 新增
2435
- - **文档增强**:为 `distinct` 方法添加完整的文档、示例和测试用例
2436
- - 新增 `docs/distinct.md`:详细的 distinct 方法使用文档,包含参数说明、使用模式、性能优化建议、常见问题等
2437
- - 新增 `examples/distinct.examples.js`:10 个完整示例,涵盖基础去重、条件查询、嵌套字段、数组字段展开、大小写不敏感、缓存优化、性能分析等场景
2438
- - 新增 `test/distinct.test.js`:12 个测试套件共 60+ 个测试用例,全面覆盖去重功能的各种场景和边界情况
2439
- - README.md 添加 distinct 方法说明和指向详细文档、示例、测试的链接
2440
- - **文档增强**:为 `aggregate` 方法添加完整的文档、示例和测试用例
2441
- - 新增 `docs/aggregate.md`:详细的 aggregate 方法使用文档,包含所有管道阶段、参数说明、使用模式、性能优化建议等
2442
- - 新增 `examples/aggregate.examples.js`:8 个完整示例,涵盖基础聚合、联表查询、数据转换、数组操作、日期分组、多路聚合、流式处理和性能优化
2443
- - 新增 `test/aggregate.test.js`:11 个测试套件共 50+ 个测试用例,全面覆盖聚合功能的各种场景和边界情况
2444
- - README.md 添加指向 aggregate 详细文档、示例和测试的链接
2445
- - 统一 findPage:在原 after/before 基础上,新增 `page` 跳页(书签 bm: + 少量 hops),`offsetJump` 小范围 `$skip+$limit` 兜底,`totals` 多模式(none/async/approx/sync)。
2446
- - 书签/总数缓存键:复用实例 cache;书签键前缀 `bm:`,总数键前缀 `tot:`;键采用去敏"查询形状哈希"(不含具体值)。
2447
- - 文档:README 新增并细化"统一 findPage:游标 + 跳页 + offset + totals"章节(完整参数/注释/错误码/异步 totals 轮询示例);STATUS 路线图对齐。
2448
-
2449
- ### 变更
2450
- - 重构:将 `findPage` 抽离到 `lib/mongodb/find-page.js`,index 通过工厂注入上下文;命名空间键稳定。
2451
- - 运行器:findPage 内部的单页执行与 offset 分支改为使用统一 `run()` 包装(缓存+慢日志+精确失效)。
2452
- - 跳页:`maxHops` 从“分段限制”改为“整次跳页累计限制”(更符合直觉,默认仍为 20)。
2453
- - 文档:补充“默认值一览/优先级/实例级书签默认配置示例”,细化各可选项默认行为。
2454
-
2455
- ### 修复
2456
- - totals:`countDocuments` 透传 `collation` 与 `maxTimeMS/hint`,并在失败时输出一次 warn(去敏);异步失败也缓存 `{ total:null }` 以保持语义一致。
2457
- - totals:async 的对外 token 改为短标识(`<keyHash>`),避免暴露命名空间;README 示例同步更新。
2458
- - 形状键:`queryShape/pipelineShape` 计算改进,减少不同查询碰撞同一 keyHash 的概率。
2459
- - 书签:修复推进到 anchorPage 的循环中未应用 `maxBookmarkPages` 上限的边界问题,避免过多书签键写入。
2460
-
2461
- ### 性能
2462
- - totals:新增 5s 窗口的 inflight 去重,避免同一形状的并发计数击穿。
2463
-
2464
- ### 测试
2465
- - **新增连接管理测试套件**:`test/connection.test.js`
2466
- - 验证并发连接只建立一个实例(10 并发测试)
2467
- - 验证集合名和数据库名的输入校验(空、null、空格、非字符串)
2468
- - 验证多次连接-关闭循环的资源清理(3 次循环测试)
2469
- - 验证连接锁正确清理
2470
-
2471
- ### 说明
2472
- - 推荐发布类型:`patch`(x.y.z -> x.y.(z+1)),因为是 bug 修复
146
+ **最后更新**: 2025-12-29
2473
147
 
2474
- [未发布]: ./