美文网首页
redis遇到的坑

redis遇到的坑

作者: 西谷haul | 来源:发表于2021-11-14 18:20 被阅读0次

    1、遇到的问题:

    护士提交了一封院内压疮文书,应该提交给护士长的,但是护士长却没有看到。每一封文书通过绑定不同的流程来进行不同的处理。

    2、问题排查:

    初步排查时,登陆人权限设置,不良事件表数据,以及流程表数据,文书绑定的流程都没有问题。继续排查发现,此文书没有到达护士长节点,进一步排查发现走的流程是错误的,但是文书绑定流程功能显示的绑定是正确的,查询此块代码,发现是,文书绑定流程,删除流程时,数据库中数据进行操作删除了,但是redis中的数据没有及时的更新。

    3、解决方案:

    如果使用redis,那么要保证和数据库数据的一致性。

    如果数据在Redis存在,应用就可以直接从Redis拿到数据,不用访问数据库。如果Redis里面没有,先到数据库查询,然后写入到Redis,再返回给应用。

    redis做缓存原理

    一旦被缓存的数据发生变化的时候,我们既要操作数据库的数据,也要操作Redis的数据。

    首先需要明确的是,不管选择哪一种方案, 我们肯定是希望两个操作要么都成功,要么都一个都不成功。不然就会发生Redis跟数据库的数据不一致的问题。但是, @Transactional(声明式事务)只能保证数据库的数据一致性问题,但是是无法控制redis中的事务的。
    (redis中也是存在事务的。可以使用自定义方法使用编程式事务 我们使用 begin(即控制reids事务也控制数据库事务)、commit、rollback 都需要实现控制redis事务和数据库事务。)

    ①先操作Redis的数据再操作数据库的数据
    ②先操作数据库的数据再操作Redis的数据

    这里我们先要补充一点,当存储的数据发生变化,Redis的数据也要更新的时候,我们有两种方案,一种就是直接更新,调用set;还有一种是直接删除缓存,让应用在下次查询的时候重新写入。
    更新缓存之前,判断是不是要经过其他表的查询、接口调用、计算才能得到最新的数据,而不是直接从数据库拿到的值,如果是的话,建议直接删除缓存,这种方案更加简单,一般情况下也推荐删除缓存方案。

    ①先更新数据库,再删除缓存
    正常情况:更新数据库,成功。删除缓存,成功。
    异常情况
    1、更新数据库失败,程序捕获异常,不会走到下一步,所以数据不会出现不一致。
    2、更新数据库成功,删除缓存失败。数据库是新数据,缓存是旧数据,发生了不一致的情况。

    这种问题怎么解决呢?我们可以提供一个重试的机制。
    比如:如果删除缓存失败,我们捕获这个异常,把需要删除的key发送到消息队列。然后自己创建一个消费者消费,尝试再次删除这个key,如图3-5所示。

    image-20210705201740430

    先删除缓存,再更新数据库

    正常情况:删除缓存,成功。更新数据库,成功。
    异常情况:

    • 删除缓存,程序捕获异常,不会走到下一步,所以数据不会出现不一致。

    • 删除缓存成功,更新数据库失败。 因为以数据库的数据为准,所以不存在数据不一致的情况。
      看起来好像没问题,但是如果有程序并发操作的情况下:

    • 线程A需要更新数据,首先删除了Redis缓存

    • 线程B查询数据,发现缓存不存在,到数据库查询旧值,写入Redis,返回

    • 线程A更新了数据库

    这个时候,Redis是旧的值,数据库是新的值,发生了数据不一致的情况,如图3-7所示,这种情况就比较难处理了,只有针对同一条数据进行串行化访问,才能解决这个问题,但是这种实现起来对性能影响较大,因此一般情况下不会采用这种做法。

    image-20210705204932980

    具体可参考https://www.cnblogs.com/xiaoyuxixi/p/15483651.html

    redis提示删除成功,但是实际上却没有删除的问题

    相关文章

      网友评论

          本文标题:redis遇到的坑

          本文链接:https://www.haomeiwen.com/subject/zijxtrtx.html