1.缓存穿透
@Overridepublic Result queryById(Long id) {//1.从redis中查询缓存String key = CACHE_SHOP_KEY + id;String shopJson = stringRedisTemplate.opsForValue().get(key);//2.判断是否存在//3.存在则直接返回if (StrUtil.isNotBlank(shopJson)){Shop shop = JSONUtil.toBean(shopJson, Shop.class);return Result.ok(shop);}//判断是否命中空值if (shopJson!=null){return Result.fail("店铺信息不存在");}//4.不存在,根据ID查询数据库Shop shop = getById(id);//5.不存在,返回错误if (shop== null){//将空值写入redisstringRedisTemplate.opsForValue().set(key,"",CACHE_NULL_TTL, TimeUnit.MINUTES);return Result.fail("店铺不存在");}//6.存在,写入redisstringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(shop));//7.返回return Result.ok(shop);}
2.缓存雪崩
3.缓存击穿
//缓存击穿public Shop queryWithMutex(Long id){//1.从redis中查询缓存String key = CACHE_SHOP_KEY + id;String shopJson = stringRedisTemplate.opsForValue().get(key);//2.判断是否存在//3.存在则直接返回if (StrUtil.isNotBlank(shopJson)){Shop shop = JSONUtil.toBean(shopJson, Shop.class);return shop;}//判断是否命中空值if (shopJson!=null){return null;}//实现缓存重建//尝试获取互斥锁boolean isLock = tryLock(LOCK_SHOP_KEY);//判断获取互斥锁是否成功if (!isLock){//失败,休眠并且重试try {Thread.sleep(500);} catch (InterruptedException e) {throw new RuntimeException(e);}queryWithMutex(id);}//成功//4.不存在,根据ID查询数据库Shop shop = getById(id);//5.不存在,返回错误if (shop== null){//将空值写入redisstringRedisTemplate.opsForValue().set(key,"",CACHE_NULL_TTL, TimeUnit.MINUTES);return null;}//6.存在,写入redisstringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(shop));unLock(LOCK_SHOP_KEY);//7.返回return shop;}