软删除与缓存需闭环配合:读取时过滤is_deleted、缓存键区分状态、删除时分级清理、命中后二次校验、配合延迟双删防旧值回填,确保逻辑删除在业务与缓存层均可见可感知。

软删除与缓存失效配合的核心,是让“逻辑删除”在业务层可见、在缓存层可感知,避免用户看到已删除数据,也防止数据库和缓存之间出现状态错位。
明确软删除的语义并透出状态
软删除不是真删,而是给记录加标记(如 is_deleted = 1 或 deleted_at IS NOT NULL)。关键在于:所有读取逻辑必须主动过滤该字段。否则缓存重建时可能把“已软删”的数据又写回去。
- 查询数据库时统一加
WHERE is_deleted = 0条件,不能依赖应用层事后判断 - 缓存键设计建议带上状态维度,例如用
user:123:active区别于user:123:all,避免混用 - 接口返回前做最终校验:即使缓存里有数据,也要检查其
is_deleted字段,不一致则立即清缓存并返回 404
软删除操作触发精准缓存清理
执行软删除时,不能只更新数据库,必须同步干预缓存——但不是简单删 key,而是按场景分级处理:
- 若该数据后续仍需被管理端查询(如回收站),可保留一个带标记的缓存副本,比如
user:123:deleted,并设置较短 TTL - 面向终端用户的读接口,应删除或覆盖原有缓存,例如:
→ 删除user:123:profile
→ 或写入空值+短 TTL:$redis->setex('user:123:profile', 30, json_encode(['status' => 'deleted'])) - 涉及关联缓存(如用户订单列表),需联动清理,可用 Redis 的 key 模式匹配(
SCAN)或提前维护反向索引
读取时兜底防御:缓存命中后二次校验
即使缓存存在,也不能直接信任其有效性。尤其在软删除高频的业务中,建议在读取缓存后追加一层轻量校验:
- 从缓存中取出数据后,检查
is_deleted字段;为减少开销,可将该字段单独存为一个轻量 key,如user:123:deleted_flag - 若发现已软删,立即调用清除主缓存逻辑,并返回标准提示(如“资源不存在”),不重建
- 对高一致性要求的场景(如权限校验),可跳过缓存直查数据库,或使用带版本号的缓存结构(
"v2|user:123"),软删除时递增版本并批量失效旧版
配合延迟双删降低竞态风险
软删除本质仍是“更新操作”,同样面临并发读写导致旧值回填的问题。可在事务提交后加入延迟双删:
- 第一步:事务内更新
is_deleted = 1后,立刻删除对应缓存 key - 第二步:启动异步任务(如通过 Redis Delayed Queue 或定时脚本),500ms–1s 后再次尝试删除该 key
- 第二次删除不报错、不重试,仅作兜底;它能覆盖掉“第一次删完、DB 提交前、某请求读到旧值并写回缓存”的窗口期
软删除不是缓存的例外情况,而是需要被缓存策略显式接纳的状态变更。只要数据库过滤、缓存清理、读取校验三个环节闭环,就能实现用户无感、系统一致的效果。











