Redis 高并发下的,缓存穿透

下面这段代码 如果1W个人同时访问的话,  从redis 拿 allUser 时, userList为空时,那么1W个人都要进入if判断语句,查询数据库,数据库压力承受不住

package com.tb.service;

import com.tb.dao.TUserMapper;
import com.tb.pojo.TUser;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

@Service
@Transactional
public class TuserServicelmpl implements  TuserService {

    @Resource
    private TUserMapper  tUserMapper;

    @Resource
    private RedisTemplate  redisTemplate;

    @Override
    public List<TUser> userlist() {

        //高并发下有点问题,此处问题:缓存穿透
        //查询缓存
        List<TUser>  userList =  ( List<TUser>) redisTemplate.opsForValue().get("allUser");
        if (userList==null){
            //查询数据库
            userList =  tUserMapper.userlist();
            redisTemplate.opsForValue().set("allUser",userList);
        }
        return userList;
    }
}

 解决方案

     Synchronized   关键字

双重检测锁 解决

 

package com.tb.service;

import com.tb.dao.TUserMapper;
import com.tb.pojo.TUser;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

@Service
@Transactional
public class TuserServicelmpl implements  TuserService {

    @Resource
    private TUserMapper  tUserMapper;

    @Resource
    private RedisTemplate  redisTemplate;

    @Override
    public List<TUser> userlist() {

        //高并发下有点问题,此处问题:缓存穿透
        //查询缓存
        List<TUser>  userList =  ( List<TUser>) redisTemplate.opsForValue().get("allUser");

        //双重检测锁
        if (userList==null){
            synchronized(this){
                //从数据库获取数据
                userList =  ( List<TUser>) redisTemplate.opsForValue().get("allUser");
                if (userList==null){
                    //缓存为空,查询数据库
                    userList =  tUserMapper.userlist();
                    redisTemplate.opsForValue().set("allUser",userList);
                }
            }


        }
        return userList;
    }
}

 

 

测试代码

 @GetMapping("/Tuser")
    public List<TUser>  querlist(){

        //多线程查询数据库
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                tuserService.userlist();
            }
        };

        //新建线程池
         ExecutorService executorService =  Executors.newFixedThreadPool(25);

         for(int i = 0 ; i<10000;i++){
             executorService.submit(runnable);
         }

        return tuserService.userlist();
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值