Redisson分布式锁解锁异常问题


    目录
  • 问题现象
  • 问题复现
  • 排查过程
  • 解决方案
    • 1、在解锁时增加判断
    • 2、优化代码
  • 总结

    问题现象
    程序中的redission执行unlock()报错如下:
    
    java.lang.IllegalMonitorStateException: attempt to unlock lock, not locked by current thread by node id:
    从报错信息可知:尝试解锁,而不是由当前线程按节点 ID 锁定
    问题复现
    
//获取锁对象
RLock lock = redissonClient.getLock(key);

try{
   //获取锁
   boolean tryLock = lock.tryLock(5, TimeUnit.SECONDS);
   if (!tryLock) {
   //抛出业务异常
   }
}catch(){
    //捕获异常
}finally{
    //解锁
    lock.unlock();
}

    排查过程
    如上代码,线程无论是否有获取锁,都是需要去执行解锁方法,当线程没有获得锁,执行unlock()就会报
    
    java.lang.IllegalMonitorStateException: attempt to unlock lock, not locked by current thread by node id:错误
    解决方案
    1、在解锁时增加判断
    
//判断要解锁的key是否已被锁定;判断要解锁的key是否被当前线程持有
if (lock.isLocked() && lock.isHeldByCurrentThread()) {
    lock.unlock();
}

    2、优化代码
    在执行unlock()确保线程已经获得锁
    
//获取锁对象
RLock lock = redissonClient.getLock(key);
boolean tryLock;
try {
    tryLock = lock.tryLock(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
    throw new Exception("获取分布式锁失败,请稍后再试");
}

if (!tryLock) {
    throw new Exception("请稍后再试");
}

try{
   //抛出业务异常
}catch(){
    //捕获异常
}finally{
    //解锁
    lock.unlock();
}

    总结
    以上为个人经验,希望能给大家一个参考,也希望大家多多支持电脑手机教程网。