业务场景:
PS:一般使用方案1,由缓存的调用者,在更新数据库的同时更新缓存
由缓存的调用者,在更新数据库的同时更新缓存
操作缓存和数据库时有三个问题需要考虑:
不存在线程安全问题场景
存在线程安全问题场景
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
不存在线程安全问题场景
存在线程安全问题场景
缓存更新策略的最佳实践方案:
@Override
public Result queryById(Long id) {
//从redis查询缓存
String key = RedisConstants.CACHE_SHOP_KEY + id;
String shopInfo = stringRedisTemplate.opsForValue().get(key);
//判断是否存在
if (StrUtil.isNotBlank(shopInfo)){
//存在则返回
Shop shop = JSONUtil.toBean(shopInfo, Shop.class);
return Result.ok(shop);
}
//不存在,则查询数据库
Shop shop = getById(id);
//不存在则返回错误
if (null == shop){
return Result.fail("店铺不存在");
}
//写入缓存 设置超时时间为30min
stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(shop), RedisConstants.CACHE_SHOP_TTL, TimeUnit.MINUTES);
//数据库存在,则返回
return Result.ok(shop);
}@Override
@Transactional
public Result update(Shop shop) {
Long id = shop.getId();
if (null == id){
return Result.fail("店铺id不能为空");
}
//1.更新数据库
updateById(shop);
//2.删除缓存
stringRedisTemplate.delete(RedisConstants.CACHE_SHOP_KEY + shop.getId());
return Result.ok();
}