关于java:解决数据库和缓存数据不一致情况延迟双删

11次阅读

共计 654 个字符,预计需要花费 2 分钟才能阅读完成。

在高并发的场景下,数据库解决数据增删改查很是单薄。有一些数据查问的频率远大于批改频率,就须要应用缓存技术,让先去申请 redis,redis 存在返回缓存数据,redis 不存在就查询数据库,返回数据的同时将数据缓存到 redis 中。

问题

读取缓存个别没有什么问题,一旦波及到数据更新:数据库或者缓存更新,就容易呈现缓存和数据库数据不统一状况。首先,数据“一致性”蕴含两种状况:

  1. 缓存有数据,那么缓存的值和数据库中的值雷同。
  2. 缓存没有数据,那么,数据库中的值必须是最新值。

在高并发的状况下,不论是先写数据库,再删缓存;还是先删缓存,再写数据库,都有可能呈现数据不统一的状况,比方:

  1. 如果删除了缓存 redis,还没来得及写库 mysql, 另一个线程就读取,发现缓存为空,则去数据库读取数据写入缓存,此时缓存中的数据为脏数据。
  2. 如果写了库,在删除缓存前,写库的线程宕机了,也会呈现数据不统一的状况。

    解决办法

    提早双删策略

    1、先删除缓存
    2、再写数据库
    3、休眠 500ms(依据统计线程读取数据和写缓存的工夫)
    (休眠的作用是以后线程等其余线程读完了数据后写入缓存后,删除缓存)
    4、再删除缓存

设置缓存过期工夫

总结

先革除缓存,而后再写入数据库。有可能存在删除缓存当前,另一个线程读取数据,发现没有数据,就去数据读取数据,而后写入缓存中,此时缓存中的数据为脏数据;
解决办法:

  1. 先删除缓存
  2. 再写入数据库
  3. 休眠 500ms
  4. 删除缓存
    其中第三步骤的 500ms,是依据业务读取数据均匀耗时,这样做的目标是确保读申请能够完结,写申请能够删除读申请造成的脏数据的问题。
正文完
 0