网络宝典
第二套高阶模板 · 更大气的阅读体验

缓存与数据库同步:别让用户刷出“昨天的订单”

发布时间:2026-04-24 00:31:42 阅读:4 次

你有没有遇到过这种情况:刚在电商 App 下完单,刷新页面发现订单还没出来;或者修改了个人资料,再进主页头像还是旧的?问题很可能出在缓存数据没对上。

缓存不是“偷懒”,是刚需

数据库读写慢,尤其高并发时,扛不住。于是加一层缓存——比如 Redis 或本地内存,把常用数据先存一份,下次直接读缓存,快十倍不止。但麻烦也来了:数据库改了,缓存还留着老数据,用户看到的就是“幻影信息”。

常见同步策略,各有脾气

写数据库后删缓存(Cache Aside):最常用。更新操作先改 DB,再把对应缓存 key 删掉。下次读时发现缓存没了,自动查库、回填新值。
优点是简单,缺点是删缓存失败或延迟时,会短暂出现脏数据。

示例代码(伪逻辑):

db.updateOrder(orderId, status); // 更新数据库
redis.del("order:" + orderId); // 立即删除缓存

写数据库前删缓存(Read-Through + Write-Through):适合强一致性要求高的场景,比如银行余额。先删缓存,再写 DB,再由缓存层主动加载新值。但多一次 DB 查询,性能略降。

双写(Write-Through):应用同时写 DB 和缓存。看似一步到位,实则风险最大——万一缓存写成功、DB 写失败,数据就彻底错乱了,不推荐新手用。

现实中的坑,比文档多

删缓存不是“删完就完事”。比如缓存 key 命名不统一,更新订单用了 order:123,而查询走的是 user:456:orders,删了等于没删。再比如分布式环境下,多个服务实例同时删缓存,可能因网络延迟造成“删了又写、写了又删”的抖动。

还有个经典场景:用户连点两次“提交评论”,后端没做幂等,结果数据库多插一条,缓存却只删了一次,导致缓存里漏掉一条最新评论——页面刷新后,第二条评论才冒出来。

所以,光靠删缓存不够,得加一点“保险”:比如给缓存设较短过期时间(比如 5 分钟),即使删失败,最多等几分钟也能自动刷新;或者关键路径加版本号字段,读缓存时校验 version 是否匹配 DB,不一致就强制回源。

小建议,真能省心

开发时别图快直接写死缓存逻辑。把缓存操作封装成统一方法,比如 cacheManager.updateOrder(order),内部自动处理删 key、更新关联列表、发 MQ 清理其他节点缓存。上线前,用压测工具模拟并发更新+读取,盯紧缓存命中率和 DB 慢查日志——数据不同步的问题,往往藏在那几毫秒的延迟里。