编辑 | blame | 历史 | 原始文档

功能测试报告_导出缓存改用数据指纹_2026-09-22

一、功能说明

用户诉求:下载过一次、期间没有新导入数据就应直接沿用上次结果(已实现落盘缓存);随后用户认可「按我说的做」,要求继续解决缓存守卫的两个问题:

  1. 误失效:原来用全局 MAX(import_batch.id) 当版本号,导入投资/能耗这类与汇总大表无关的数据也会让缓存失效,白等十几秒;
  2. 漏失效(正确性漏洞):版本号只反映数据库导入记录,**不含母版文件**——换母版/改参照件时版本号不变,会把旧结果当新表发出。

改动:

# 改动 说明
1 用**数据指纹**替代全局版本 指纹 = 「依赖源表的内容校验和」+「母版等文件身份」,SHA-256 取前 8 字节(16 位十六进制),写进缓存文件名
2 源表范围=**排除法** 库内所有基表,**排除**投资(3)/能耗(2)/审核(4)/系统(6)/import_batch(1) 共 16 张;其余一律纳入(宁可多算不可出错)
3 用 CHECKSUM TABLE 取校验和 能捕捉**原地 UPDATE**(行数、max(id) 都不变的情况),比 count+max(id) 更严格
4 文件身份 母版目录下全部文件(母版 / 参照件 / _备份_ 回填件)+《网约车订单及全省总量.xlsx》,取「名称+大小+修改时间」
5 新增**失效提示**(第 3 步的提示版) 没命中且存在旧结果时,进度弹窗显示「上次生成的结果已因数据或母版变化失效,本次按最新数据重算。」

提示放在**导出时的进度弹窗**(而不是导入结果弹窗):① 正好出现在用户等待的时候;② 免去「每次导入都跑一遍全表校验和」的开销。

二、测试环境

  • 后端 Spring Boot 8090(重启加载新代码);前端 8080;MySQL 3308 / traffic_audit
  • 报表期 2026-08(月报);缓存目录 docs/生成汇总大表/_cache/
  • 验证期间另一个会话重启过后端两次,个别步骤中断后重跑(不影响结论)

三、用例表

# 用例 操作 预期 实际 结论
T01 首次生成(新指纹) 提交导出 真算并落盘,旧版本文件被清理 DONE 21 s;生成 …_v227060ce99767ced.xlsx,原 …_v541.xlsx 已删 通过
T02 再次提交 同上报 内存命中 241 ms,fromCache=true 通过
T03 无关导入不影响缓存(核心) 往 investment_project、import_batch 各插 1 行后提交 仍命中 fromCache=true(改造前必然失效) 通过
T04 删除上述两行后提交 同上 仍命中 fromCache=true 通过
T05 相关源表原地 UPDATE wyc_order_monthly.pin_k +0.001(行数/max(id) 不变)后提交 必须失效 fromCache=false、RUNNING;缓存文件名换成新指纹 …_v68b6bc0c… 通过
T06 还原该值后提交 同上 仍不命中(缓存是改后指纹) fromCache=false → 重算;指纹回到 227060ce99767ced 通过
T07 换母版必须失效(原漏洞) 改母版文件修改时间(内容不变)后提交 必须失效 fromCache=false、RUNNING;指纹变 …_v7d65cbb6… 通过
T08 恢复母版时间后提交 同上 失效→重算→再提交命中 重算后 fromCache=true 通过
T09 失效提示(接口) 存在旧结果且指纹不符时提交 staleCache=true status=RUNNING fromCache=false staleCache=true 通过
T10 命中缓存无提示(回归修复) 命中时提交 staleCache=false 修复前命中仍带 staleCache=true → 已修为命中即清零 通过
T11 浏览器实测提示行 admin/123456 → 报表生成 → 汇总大表 → 2026-08 → 导出(先改母版 mtime 制造失效) 弹窗出现失效提示 弹窗显示「上次生成的结果已因数据或母版变化失效,本次按最新数据重算。」;生成 13.2 s、自动下载 1.15 MB、按钮「重新生成/关闭」、控制台 0 报错 通过
T12 数据还原核对 查库 无测试残留 import_batch 419、investment_project 152、wyc_order_monthly.2025-12 pin_k=3492.63、无「_指纹测试项目」 通过

四、发现的问题与处置

# 问题 处置
P1 命中缓存时残留上一次的「已失效」提示标记 已修:命中分支清零 staleCache
P2 文件身份用毫秒级 mtime:把母版 mtime「恢复成同一秒」时,亚秒差异仍会产生新指纹(验证中实际遇到) 属**预期行为**(保守优先:宁可多算一次)。若将来觉得太敏感,可改为「秒级 mtime」或对母版做内容哈希
P3 测试用的临时数据(1 个投资项目、1 条导入记录、wyc pin ±0.001) 已全部还原/删除,T12 已核对
P4 数据指纹计算成本 约 11 张表 CHECKSUM + 13 个文件 stat,实测可为毫秒级(3 张表 48 ms);仅在提交导出时算一次

五、结论

  • 缓存守卫从「全局导入版本」升级为「**数据指纹**」后:**无关导入不再让缓存失效**(T03/T04),**换母版、改源表(含原地 UPDATE)必定失效**(T05/T07),两个方向都实测通过;
  • 生成一次的成本只花在真正需要重算的时候;正常「下载过再看一次」仍是毫秒级命中;
  • 失效时会在进度弹窗明确说明原因,用户不会误以为缓存坏了;
  • 测试数据已全部还原,库内状态与验证前一致。

测试人:Codex(AI) 测试日期:2026-09-22