//redis中的key进行字符串序列化
redisTemplate.setKeySerializer(new StringRedisSerializer());
//首先去redis缓存中判断是否有值
Double historyAverageRate = (Double) redisTemplate.opsForValue().get(Constant.HISTORY_AVERAGE_RATE);
//解决缓存穿透问题:使用了两次判断与加锁,其主要目的就是只让一个线程访问数据库,其他的线程都让他们从缓存中获取数据
//第一次的判断缓存中是否有数据,就可以将多个一起访问的线程提取出来
//然后就通过加锁,只让一个线程访问数据库,这个线程会把数据写到缓存中
//最后进行第二次判断缓存中是否有数据(肯定有,因为第一个拿到锁的进程已经将数据放到缓存中了),这样其它进程都从缓存中获取了数据
//没有值就去数据库中查找,然后放到redis缓存中
if (!ObjectUtils.allNotNull(historyAverageRate)){
//如果为空,进行加锁
synchronized (this){
//再次从缓存中获取值进行判断
historyAverageRate = (Double) redisTemplate.opsForValue().get(Constant.HISTORY_AVERAGE_RATE);
if (!ObjectUtils.allNotNull(historyAverageRate)){
System.out.println("从数据库中查询数据");
historyAverageRate = loanInfoMapper.selectHistoryAverageRate();
redisTemplate.opsForValue().set(Constant.HISTORY_AVERAGE_RATE, historyAverageRate, 15, TimeUnit.SECONDS);
}else {
System.out.println("从redis中查询");
}
}
}else {
System.out.println("从redis中查询");
}
return historyAverageRate;