Redisson 分布式锁简单应用

    RLock rLock = redissonClient.getLock("lockName");// 可以看做是获取一个连接
    try {
        // 尝试加锁 愿意等待的时长 waitTime ; 加锁成功后自动释放锁的时长 leaseTime,大于0时不论加锁业务是否处理完毕都会释放锁 
        boolean locked = rLock.tryLock(1000, 2000, TimeUnit.MILLISECONDS);// 尝试加锁
        if(locked){
            // todo 加锁成功需要处理的业务处理
        }else{
            // todo 加锁失败需要处理的业务
        }
    }catch (Exception e) {// 
       throw e; // 加锁失败 和 业务处理失败后 需要做的事情
    } finally {
        try{
            rLock.unlock();// 这个很要命 手动释放锁  unlock 异常后是否需要
         }catch(Exception e){
              // 释放锁失败 要做的处理(忽略异常 还是 继续抛出异常,还是 强制释放锁)  
          }
    }

一、先做点解释

1、参数 

        waitTime  为了获取锁愿意等待的时长 <= 0 不愿意等待,即没有获取到锁时直接返回false

        leaseTime 加锁成功后自动释放锁的时长,>0 时 不论锁定的业务是否执行完毕都会在这个时间到期时释放锁---这个很要命;=-1表示这个锁不会自动释放必须手动释放,看门狗每10秒(默认配置)延期一次锁(实际是重置锁的过期时间为30秒:默认配置)

2、上图伪代码仅供参考

二、结论

        1、根据自身业务 谨慎并合理设置 waitTime  和 leaseTime 值 ;

        2、finally 中一定要 手动释放锁 rLock.unlock(); ---锁定的资源在业务处理完毕后尽快释放,不论是否设置了自动释放锁;

三、加锁的lua脚本

"if (redis.call('exists', KEYS[1]) == 0) then " +
    "redis.call('hincrby', KEYS[1], ARGV[2], 1); " +
    "redis.call('pexpire', KEYS[1], ARGV[1]); " +
    "return nil; " +
    "end; " +
    "if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " +
    "redis.call('hincrby', KEYS[1], ARGV[2], 1); " +
    "redis.call('pexpire', KEYS[1], ARGV[1]); " +
    "return nil; " +
    "end; " +
    "return redis.call('pttl', KEYS[1]);"

KEYS[1]=lockName,ARGV[2]=hash中的key=redisson客户端节点id+线程id,ARGV[1]=锁的过期时间

上一篇:AT4995-[AGC034E] Complete Compress【树形dp】


下一篇:U3D台球项目模板 8 Ball Pool Complete Game Template