缓存击穿:
对于某一个缓存,在高并发情况下若其访问量特别巨大,当该缓存的有效时限到达时,可能会出现大量的访问都要重建该缓存,即这些访问请求发现缓存中没有该数据,则立即到 DBMS 中进行查询,那么这就有可能会引发对 DBMS 的高并发查询,从而接导致 DBMS 的崩溃。这种情况称为缓存击穿,而该缓存数据称为热点数据。
步骤如下:
- 先查 reids 中是否有数据
- 如果 redis 中没有数据,使用 synchronized 进行加锁
- 再次查询 reids 中是否有数据
- 如果第3步查询还是没有数据,此时再查数据库
- 查询到数据库中的数据后,将数据写入到redis中
public Double findTurnover() {
// 获取Redis操作对象
BoundValueOperations<Object, Object> ops = template.boundValueOps("turnover");
// 从缓存获取turnover
Object turnover = ops.get();
//取不到加锁
if (turnover == null) {
synchronized (this) {
turnover = ops.get();
// 若缓存中没有,则从DB中查询
if (turnover == null) {
Date date = new Date();
//根据当前时间获取交易额
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
turnover = dao.selectTurnover(sdf.format(date));
// 将从DB中查询的结果写入到缓存,并指定过期时间
ops.set(turnover, 10, TimeUnit.SECONDS);
}
}
}
return (Double) turnover;
}
使用双重检查锁的方法,可以避免高并发情况下,所有请求直接到数据库上