更新接口返回 false 时,旧缓存还在吗?清理某个商户时,同一缓存区域的其他租户是否受影响?这两个问题分别涉及调用结果和失效范围,需要独立验收。
资料基于 Spring Framework 7.0.10。原始核查:2026 年 10 月 25 日;发布整理复核:2026 年 10 月 30 日 JST。以下练习尚未运行,先以即时执行的本地缓存隔离事务与 Redis 故障。
正常返回与业务成功不是同一个条件
@CacheEvict 默认在被拦截方法正常完成后触发。方法抛异常时,不执行这次默认的调用后失效;正常返回 false 或失败 DTO,仍然属于正常完成。框架不会自动理解返回值中的业务失败含义。CacheEvict API
beforeInvocation=true 改为方法调用前触发。已经发生的失效不会因为后续方法抛错而自动恢复。若缓存操作本身失败,能否继续进入方法又取决于错误处理策略,应与本节无缓存故障的基线分开验证。
练习一:true、false、异常三组结果
启用缓存注解,经 Spring 代理调用独立测试 Bean,使用 ConcurrentMapCache。每组预放商户键 1001,然后分别让方法返回 true、返回 false、抛出异常;对照默认设置与 beforeInvocation=true,记录方法是否执行、异常及条目是否存在。
再为调用后组增加 condition="#result == true",验证返回 false 时保留缓存。表达式只适用于这里具有布尔返回值的调用后组;调用前还没有结果,不能引用它。固定版本注解源码明确限定了 #result 可用时点。
allEntries 清理的是整个缓存区域
默认失效按键进行。allEntries=true 清理指定缓存区域的所有条目;它没有按商户、租户或业务权限自动缩小范围的含义。练习中的全区清除方法只设置 allEntries=true,不同时配置 key。失效指南
在一个测试区域预放两个不同租户的假商户键,另一缓存区域放一个负对照条目。比较指定 key 的失效与全区清除:前者只应移除目标键,后者应影响同一区域两个键,另一缓存区域保持不变。
验收表必须记录清除前后的所有相关键。只证明目标键消失,并不能证明影响范围正确。
把触发时点放回事务和并发场景
这里的方法正常返回不等于数据库最终提交。事务感知装饰器、缓存异常和并发旧值回填需要另外检查;通过返回值设置 condition 只是本练习的业务契约选择,不能套给所有更新接口。
衔接阅读:事务与事件边界和旧读回填实验。本文没有运行 Java 或 Redis,也没有核实既有 6.2.11 项目的全部兼容性;来源独立发布日期未标明。