Redisson分布式锁解锁异常

问题现象

程序中的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();
}

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Redisson 是一个开源的分布式锁框架,它提供了一种方便易用的方式来实现分布式锁。而"连锁"指的是在 Redisson 中,可以通过使用 RLock 对象来实现分布式锁的连锁特性。 在 Redisson 中,RLock 对象是一个可重入的分布式锁,它支持连锁特性。连锁特性指的是当一个线程获取到锁后,其他线程只能等待,直到获取到锁的线程释放锁。而在 Redisson 中,RLock 对象可以通过 lock() 方法获取锁,并通过 unlock() 方法释放锁。 使用 Redisson 进行分布式锁的连锁操作可以保证在同一个线程中进行多次加锁和解锁操作时,其他线程无法获取到锁。这种连锁特性能够确保在一个线程中执行一系列的操作时,其他线程无法干扰。 下面是一个示例代码,演示了 Redisson 分布式锁的连锁特性: ```java // 初始化 Redisson 客户端 Config config = new Config(); config.useSingleServer().setAddress("redis://127.0.0.1:6379"); RedissonClient redisson = Redisson.create(config); // 获取分布式锁 RLock lock = redisson.getLock("myLock"); lock.lock(); try { // 执行一系列需要加锁的操作 // ... } finally { // 释放锁 lock.unlock(); } // 关闭 Redisson 客户端 redisson.shutdown(); ``` 在上面的示例中,通过 Redisson 的 getLock() 方法获取到一个名为 "myLock" 的分布式锁对象。然后使用 lock() 方法进行加锁,在 try-finally 语句块中执行一系列需要加锁的操作,最后使用 unlock() 方法释放锁。 需要注意的是,在使用 Redisson 进行分布式锁时,确保每次获取锁后都要通过 unlock() 方法释放锁,否则可能会导致死锁或资源争用的问题。此外,建议在 finally 块中释放锁,以确保无论是否发生异常都能够正确释放锁。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值