<!-- generated-by: gsd-doc-writer -->
# 服务缓存接入

规则 `CORE-CACHE-001`。2026-09-19 对照同步与响应式缓存源码。

## 选择运行时

| 业务引擎 | 缓存模块 | 主要依赖 |
| --- | --- | --- |
| `ineed-core-engine` | `ineed-core-service-cache` | Spring Cache 的 `CacheManager` 与同步事务协调 |
| `ineed-core-engine-reactive` | `ineed-core-service-cache-reactive` | Reactive store/Redis 与响应式事务协调 |

两套模块含同包同名契约，分别用于独立运行时。不能将阻塞缓存引入响应式应用作为复用手段。

## 声明缓存

Service 的可选缓存能力由 `IServiceCache.getServiceCacheSpec()` 提供；默认返回 `null`，表示不启用。规格由 `ServiceCacheSpec` 描述缓存名称及各读取能力开关。

源码：[IServiceCache](../../ineed-core-modules/ineed-core-service-cache/src/main/java/com/ineed/core/service/cache/IServiceCache.java)、[ServiceCacheSpec](../../ineed-core-modules/ineed-core-service-cache/src/main/java/com/ineed/core/service/cache/ServiceCacheSpec.java)。

接入步骤：确认查询适合缓存 → 提供明确 cache name 和规格 → 确认运行时实际有 cache/store → 检查标准读取能力与自定义方法的注解 → 确认全部写入口的失效范围 → 验证隔离与回滚。

自定义只读方法使用 `@ServiceCacheable` 时仍要满足 Service 策略与 Spring 代理条件；`@ServiceCacheEvict` 用于成功写入后的失效。同步标准 CRUD、账户、状态及排序 Service 写方法也使用该注解，清理当前目标租户登记的缓存 key；业务覆盖标准方法或新增写动作时需保留对应失效声明，避免用 `@CacheEvict(allEntries=true)` 替换。自调用不会自动经过代理。

## Key 与权限

Core 缓存包含租户隔离契约。业务仍需判断结果是否还依赖用户、角色、数据范围、语言等条件；有租户 key 不等于所有个性化查询都安全。无法稳定表达授权上下文的结果，优先不缓存。

不要用另一个模块的 cache name，也不要在绕过 Service 的仓储写入后假定缓存一定失效。自定义写动作必须被纳入失效测试。

## 提交与回滚

同步 [ServiceCacheAfterCommitCoordinator](../../ineed-core-modules/ineed-core-service-cache/src/main/java/com/ineed/core/service/cache/ServiceCacheAfterCommitCoordinator.java)在有事务时协调提交后失效；回滚不执行该提交动作，无事务时在方法成功返回后执行。`REQUIRES_NEW` 挂起外层失效批次，内层提交独立失效，再恢复外层批次；外层回滚不能吞掉已提交内层的失效。

响应式 [ReactiveServiceCacheAfterCommitCoordinator](../../ineed-core-reactive-modules/ineed-core-service-cache-reactive/src/main/java/com/ineed/core/service/cache/reactive/ReactiveServiceCacheAfterCommitCoordinator.java)组合源 Publisher 与响应式事务同步。未订阅不得执行缓存工作。

事务成功后缓存失效仍可能失败；这不等于数据库回滚。业务应根据一致性要求设计重试、告警或补偿，不能把本地缓存接口当作可靠消息系统。

## 验证

同租户命中、不同租户隔离、写后失效、事务内不提前失效、回滚保留原缓存、无事务行为、响应式未订阅无动作。可运行依据：[提交后协调测试](../../ineed-core-modules/ineed-core-service-cache/src/test/java/com/ineed/core/service/cache/ServiceCacheAfterCommitCoordinatorTest.java)、[缓存注解集成测试](../../ineed-core-modules/ineed-core-service-cache/src/test/java/com/ineed/core/service/cache/ServiceCacheAnnotationIntegrationTest.java)。这些测试不代表已连接生产 Redis。

标准默认方法的真实代理验证见 [StandardServiceCacheTransactionTest](../../ineed-core-modules/ineed-core-engine/src/test/java/com/ineed/core/service/cache/StandardServiceCacheTransactionTest.java)：覆盖外层事务、提交前旧值回填、回滚、其他租户保留、Service 自身事务和 `REQUIRES_NEW`。测试采用默认 Spring 事务 Advisor 顺序；应用若自定义 Advisor 顺序，应让事务拦截器包住缓存失效拦截器（事务 order 数值更小），并运行同类传播测试。独立事务的四种提交/回滚组合见 [RequiresNewCacheEvictionTest](../../ineed-core-modules/ineed-core-service-cache/src/test/java/com/ineed/core/service/cache/RequiresNewCacheEvictionTest.java)，使用真实 H2 事务。
