但凡说到缓存,那就不得不考虑到缓存和数据库不一致问题
首先就是缓存和数据库双写不一致问题,也就是先更新数据库再更新缓存
情景1:
- 线程A更新了数据库
- 线程B更新了数据库
- 线程B更新了缓存
- 线程A更新了缓存
- 线程C读取缓存,嗯?怎么是这个?
情景2:
- 线程A更新了数据库
- 线程A更新了缓存
- 线程A程序出错,业务回滚
- 线程B读取缓存,嗯?这是啥?
以上两种情况都会导致缓存数据和数据库数据不一致
故为防止缓存和数据库双写不一致问题,可采用 更新数据库+删除缓存 方案,当我们在缓存上查不到数据时,前往数据库读取
方案1:先删除缓存再更新数据库
情景1:
- 线程A更新了数据库
- 线程B更新了数据库
- 线程B删除了缓存
- 现在A删除了缓存
- 线程C读取缓存,嗯?没有了!
- 线程C读取数据库
- 线程C写入缓存
情景2:
- 线程A更新了数据库
- 线程A更新了缓存
- 线程A程序出错,业务回滚
- 线程B读取缓存,嗯?没有了!
- 线程B读取数据库
- 线程B写入缓存
理论上是解决了缓存和数据库双写一致问题,那这样呢?
- 线程A删除了缓存
- 线程B查询缓存查询不到
- 线程B查询数据库,并写入缓存
- 线程A更新数据库
- 线程C读取缓存,卧槽!怎么还是你!
搞不定,那就倒过来试试
方案2:先更新数据库再删除缓存
- 线程A更新了数据库
- 线程A删除了缓存
- 线程B读取缓存,诶,没有了
- 线程B读取数据库
- 线程B写入缓存
- 线程C读取缓存,嗯!终于逮到你了
理论上来说,这次应该是差不多了
但是,社会是险恶的,删除缓存命令也是有可能会失败地!!!
当遇到删除失败时,可以把删除任务新增到任务队列中,定时重试
倘若你的程序对数据的一致性和实时性都有极高的要求时,那就只能说明: 你的程序不适合使用缓存