使用Redis构建分布式锁

1.为何要构建分布式锁redis

  由于多实例的分布式运行状况下,某些代码块会存在竞争关系,例如定时关单,假如部署的tomcat集群为3台A,B,C,有一个定时任务,去清除过时订单,则Tomcat 会出现同时执行某个任务的状况tomcat

2.redis分布式锁原理多线程

     使用setnx getset指令分布式

//    @Scheduled(cron="0 */1 * * * ?")//每1分钟(每一个1分钟的整数倍)
    public void closeOrderTaskV3() throws InterruptedException {
        //防死锁分布式锁
        long lockTimeout = Long.parseLong(PropertiesUtil.getProperty("lock.timeout","50000"));//锁50秒有效期
        //项目因为历史数据关单订单比较多,须要处理,初次用50s时间,后续改为5s便可.同时50s也为了讲课debug的时候时间长而设置。
        //你们能够根据实际状况,若是历史订单都处理完毕,或者在外部进行洗数据ok,这里的lock的时间应该设置小一些,例如1s 2s 3s 4s 5s就足够啦。
        //这个时间如何用呢,看下面。和时间戳结合起来用。
        Long setnxResult = RedisShardedPoolUtil.setnx(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK, String.valueOf(System.currentTimeMillis()+lockTimeout));
        if(setnxResult != null && setnxResult.intValue() == 1){
            //若是返回值是1,表明设置成功,获取锁
            closeOrder(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);
        }else{
            //若是setnxResult==null 或 setnxResult.intValue() ==0 即 != 1的时候
            //未获取到锁,继续判断,判断时间戳,看是否能够重置获取到锁
            String lockValueStr = RedisShardedPoolUtil.get(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);

            //若是lockValue不是空,而且当前时间大于锁的有效期,说明以前的lock的时间已超时,执行getset命令.
            if(lockValueStr != null && System.currentTimeMillis() > Long.parseLong(lockValueStr)){
                String getSetResult = RedisShardedPoolUtil.getSet(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK,String.valueOf(System.currentTimeMillis()+lockTimeout));
                //再次用当前时间戳getset,
                //返回给定 key 的旧值。  ->旧值判断,是否能够获取锁
                // 当 key 没有旧值时,即 key 不存在时,返回 nil 。 ->获取锁
                //这里咱们set了一个新的value值,获取旧的值。
//运用多线程的CAS原理,只有在旧值没有被修改的状况下,才能拿到锁
                if(getSetResult == null || (getSetResult !=null && StringUtils.equals(lockValueStr,getSetResult))){
                    //获取到锁
                    closeOrder(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);
                }else{
                    log.info("没有得到分布式锁:{}",Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);
                }
            }else{
                log.info("没有得到分布式锁:{}",Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);
            }
        }
相关文章
相关标签/搜索