欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

redis实现分布式锁

程序员文章站 2022-03-30 19:53:21
...

一、防重情况一:并发情况下只有一个执行,但串行情况(使用线程池)下可以执行多次

        RLock rLock = redissonClient.getLock("key-"+msgId);
        boolean getLock = false;
        try {
            if(rLock.tryLock(5,60 * 60 * 24 * 7, TimeUnit.SECONDS)){
                getLock = true;
                this.doBusiness(msgBo,msgId);
            }else{
                log.warn("can not lock:{}",msgId);
            }
        } catch (Exception e) {
            log.error("deal error,msgId={}",msgId,e);
            //当前业务处理失败,释放锁
            if(rLock != null && rLock.isHeldByCurrentThread()){
                rLock.unlock();
            }
            throw new RuntimeException(e);
        }
        if(!getLock){
            throw new RuntimeException("can not get lock");
        }

   以上发生重复执行的原因,在于虽然设置了加锁时间7天,但如果使用的是线程池,可能后续同一线程消费MQ消息。所以能获取到分布式锁。

 

二、防重情况二:并发情况下只有一个执行,指定时间范围内不能再执行

       String key = "key-"+msgId;
        boolean getLock = false;
        try{
            if(redisClient.setNx(key,"Y",60*60*24*7)){
                getLock = true;
                this.doBusiness(msgBo,msgId);
            }else{
                log.warn("can not lock:{}",msgId);
            }
        }catch (Exception e) {
            log.error("deal error,msgId={}",msgId,e);
            //当前业务处理失败,释放锁
            if(getLock){
                Long delResult = redisClient.del(key);
                log.info("delResult = {}",delResult);
            }
            throw new RuntimeException(e);
        }
        if(!getLock){
            throw new RuntimeException("can not get lock");
        }

 

 

相关标签: redis