Laravel 10中软删除与缓存协同需主动规避冲突:默认查询自动过滤软删记录,缓存前应确保使用标准查询(如User::get());delete/restore不自动刷新缓存,须手动清除(如Cache::forget('user:123'))或在deleted/restored事件中处理;禁用withTrashed()结果缓存于高频路径。

在 Laravel 10 中,数据库缓存与软删除是两个独立但常需协同处理的机制。缓存关注数据读取性能,软删除关注数据逻辑生命周期——当两者交叉时(比如缓存了已被软删除的模型),容易出现“数据陈旧”或“状态不一致”问题。关键不是让缓存自动感知 deleted_at,而是通过设计规避冲突。
缓存前主动排除软删除记录
最稳妥的做法是在写入缓存前,确保查询结果已过滤掉软删除数据。Eloquent 默认就如此:普通查询(如 User::get())天然跳过 deleted_at IS NOT NULL 的行。因此,只要用标准方式查数据再缓存,就不会把已软删的记录误存。
- ✅ 推荐写法:Cache::remember('users:active', 3600, fn() => User::where('status', 'active')->get())
- ❌ 避免写法:Cache::remember('all_users', 3600, fn() => User::withTrashed()->get()) —— 这会把已删除用户也缓存进去,且后续恢复操作不会自动刷新该缓存
软删除/恢复后及时清理相关缓存
调用 delete() 或 restore() 本身不会触碰缓存。若缓存键依赖于某条记录(如 user:123),而该记录被软删除或恢复,必须手动清除对应缓存,否则下次读取仍返回旧状态。
- 恢复用户后刷新其缓存:Cache::forget('user:123')
- 批量恢复评论时,可结合主键生成缓存键并批量清除:Cache::delete(['comment:45', 'comment:46'])
- 更健壮的方式:在模型的 restored 和 deleted 事件中触发清理逻辑
避免缓存 withTrashed() 查询结果
withTrashed() 和 onlyTrashed() 是调试或管理后台专用查询方式,不应进入高频缓存路径。这类结果集语义不稳定(随时可能被 restore 或 forceDelete),缓存后极易失效或引发业务误判。
- 如确需缓存“回收站列表”,建议使用独立缓存键(如 trashed_posts:admin_7),并设置较短 TTL(如 5 分钟)
- 绝不复用面向前端的通用缓存键(如 posts:list)来存储含软删数据的结果
事务中同步更新缓存与软删除状态
当软删除恢复操作涉及多步联动(例如恢复订单 + 同步更新库存 + 记录审计日志),应在同一 DB::transaction() 中完成,并在事务提交成功后再执行缓存清理。这样可防止数据库已恢复但缓存未更新的中间态。
- 示例顺序:查询软删记录 → restore() → 更新关联表 → Cache::forget(...) → 事务提交
- 若清理缓存失败(如 Redis 不可用),可记录告警但不中断事务;后续靠缓存 TTL 自动过期兜底


















