• redis分布式锁


    1:使用redis自带的分布式锁,set px nx

    set key 1 px 60000 nx

    px 过期时间      nx 分布式锁参数,只有当不存在时,才可设置成功

     public String getUser(String key) {       
            User user = new User();
            // 链接缓存
            Jedis jedis = redisUtil.getJedis();
            // 查询缓存
            String userJson = jedis.get(key);       
            if(StringUtils.isNotBlank(userJson)){//if(userJson!=null&&!userJson.equals(""))           
                user = JSON.parseObject(userJson, User.class);
            }else{ // 如果缓存中没有,查询mysql
                // 设置分布式锁
                String token = UUID.randomUUID().toString();
                String OK = jedis.set(key + ":lock", token, "nx", "px", 10*1000);// 拿到锁的线程有10秒的过期时间
                if(StringUtils.isNotBlank(OK)&&OK.equals("OK")){
                    // 设置成功,有权在10秒的过期时间内访问数据库              
                    user =  getByIdFromDb(key);
                    if(user!=null){
                        // mysql查询结果存入redis
                        jedis.set(key+":info",JSON.toJSONString(user));
                    }else{
                        // 数据库中不存在该key
                        // 为了防止缓存穿透将,null或者空字符串值设置给redis
                        jedis.setex(key+":info",60*3,JSON.toJSONString(""));
                    }
                    // 在访问mysql后,将mysql的分布锁释放
                    String lockToken = jedis.get(key + ":lock");
                    if(StringUtils.isNotBlank(lockToken)&&lockToken.equals(token)){
                        //jedis.eval("lua");可与用lua脚本,在查询到key的同时删除该key,防止高并发下的意外的发生
                        jedis.del(key + ":lock");// 用token确认删除的是自己的key的锁
                    }
                }else{
                    // 设置失败,自旋(该线程在睡眠几秒后,重新尝试访问本方法)          
                    return getUser(key);
                }
            }
            jedis.close();
            return user;
        }

    reids的工具类RedisUtil 

    //reids的工具类(用来将redis的池初始化到spring容器中)
    public class RedisUtil {
        private  JedisPool jedisPool;
        public void initPool(String host,int port ,int database){
            JedisPoolConfig poolConfig = new JedisPoolConfig();
            poolConfig.setMaxTotal(200);
            poolConfig.setMaxIdle(30);
            poolConfig.setBlockWhenExhausted(true);
            poolConfig.setMaxWaitMillis(10*1000);
            poolConfig.setTestOnBorrow(true);
            jedisPool=new JedisPool(poolConfig,host,port,20*1000);
        }
        public Jedis getJedis(){
            Jedis jedis = jedisPool.getResource();
            return jedis;
        }
    }
    View Code

    redis的配置类RedisConfig 

    //spring整合redis的配置类 将redis的链接池创建到spring的容器中
    @Configuration
    public class RedisConfig {
        //读取配置文件中的redis的ip地址
        @Value("${spring.redis.host:disabled}")
        private String host;
        @Value("${spring.redis.port:0}")
        private int port ;
        @Value("${spring.redis.database:0}")
        private int database;
        @Bean
        public RedisUtil getRedisUtil(){
            if(host.equals("disabled")){
                return null;
            }
            RedisUtil redisUtil=new RedisUtil();
            redisUtil.initPool(host,port,database);
            return redisUtil;
        }
    }
    View Code

    2:redisson框架,一个redis的带有juclock功能的客户端的实现(既有jedis的功能,又有juc的锁功能)

  • 相关阅读:
    [Oracle DBA学习笔记] STARTUP详解
    亦步亦趋完成在CentOS 6.4下安装Oracle 11gR2
    ‘程序员’与‘页面仔’
    Linux下建立Oracle服务及其开机自启动
    解析并验证IE6及之前版本的'!important’ BUG
    浅谈CSS选择器中的空格
    在CentOS安装CMake
    关于CentOS下RPM的一些实例
    CentOS配置ssh无密码登录的注意点
    CentOS下的账户管理
  • 原文地址:https://www.cnblogs.com/fuyublog/p/12010848.html
Copyright © 2020-2023  润新知