159-如何解决缓存穿透?

     //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;

猜你喜欢

转载自www.cnblogs.com/pogusanqian/p/12815279.html