商户查询缓存(利用互斥锁解决缓存击穿)
案例:
我们这里如何模拟互斥锁:
1、我们用redis的setnx命令来模拟锁,他的逻辑是如果不存在这个key的时候才改变。如果key存在就无法改变
第一步:(我们先设置两个方法分别设置锁和释放锁)
这里我们不直接返回这个flag。因为它的类型是Boolean,而他的方法是一个boolean(一个Boolean的包装类)我们如果直接拆箱的话可能会出现空指针。我们用Booleanuntil工具类。
设置锁:
释放锁:
第二步:改变逻辑(再写一个解决缓存击穿的方法)
我们是通过这个去调用是解决缓存击穿还是缓存穿透(这里我们调用的是缓存击穿)
说一下我们的逻辑:
这里我们的4缓存重建。我们怎么缓存重建呢,我们要去访问我们的数据库资源再写回redis而我们就需要再我们访问数据库资源之前给他加一个互斥锁,再判断下锁是否存在才能去查询我们的数据库资源再写到redis,完了再释放掉锁,返回数据再结束。
4.1、获取互斥锁
4.2、判断是否成功获取锁
4.3、失败,则休眠并重试(我们这里就直接递归前面的了)
4.4、成功,根据id查询数据库(这里我们获取到锁后并且查到有锁后我们应该再次检测一下redis缓存是否存在(前面没命中可能不是他没有只是没有命中罢了),若是存在我们就无须再重建缓存了)
我们再给前面4.3的sleep做个抛异常try/catch加上7后加8
高并发模拟我们使用apache JMeter
结果:(控制台确只有一条sql)