缓存击穿:⼤量的并发请求同时访问同⼀个在redis中不存在的数据,就会导致⼤量的请
求绕过redis同时并发访问数据库,对数据库造成了⾼并发访问压⼒。
也就是当并发请求同时到达,查询redis中没有数据,请求同时取数据库查询
//解决方案
使⽤双重检测锁解决缓存击穿问题
加锁,再次查询redis,
加锁使得并发请求只有一个进入数据库查询,查询成功后将数据放入到redis,
再次从redis中取数据
public ResultVo selectAllCategories() {
List<Category> res = null;
String resStr = stringRedisTemplate.boundValueOps("res").get();
try {
if (resStr != null) {
JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, Category.class);
res = objectMapper.readValue(resStr, javaType);
} else {
// 防止缓存击穿 加锁
synchronized (this) {
//再次从redis中取数据
String s = stringRedisTemplate.boundValueOps("res").get();
// 如果没有数据取数据库取数据并放到redis
if (s == null) {
res = categoryMapper.selectAllCategories(0);
stringRedisTemplate.boundValueOps("res").set(objectMapper.writeValueAsString(res));
} else {
//将redis中数据返回
JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, Category.class);
res = objectMapper.readValue(s, javaType);
}
}
}
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return ResultVo.ok().data("res", res);
}