//基于逻辑过期方式解决缓存基穿问题 理论上讲都是可以命中的
public Shop queryWithLogincalExpire(Long id){
//1.从redis中查商铺缓存
String jsonShop = stringRedisTemplate.opsForValue().get(CACHE_SHOP_KEY + id);
//2.未命中
if(StringUtils.isBlank(jsonShop)){
//说明根本没有该商品
return null;
}
//3.命中,需要将jsonShop进行反序列化
RedisData redisData = JSONUtil.toBean(jsonShop, RedisData.class);
JSONObject data = (JSONObject) redisData.getData();
Shop shop = JSONUtil.toBean(data, Shop.class);
//4.判断是否过期if(redisData.getExpireTime().isAfter(LocalDateTime.now())){
//未过期 直接返回
return shop;
}
String key=LOCK_SHOP_KEY+id;
//5.过期
boolean flag = tryLock(key);
//6.判断是否获得锁
if(flag){
try {
//7.是
//7.1开启独立线程
CACHE_REBUILD_EXECUTOR.submit(() -> {
//重建缓存
this.saveShop2Redis(id, 20L);
});
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
unlock(key);
}
}
//8.返回旧数据
return shop;
}