问题

redission解锁异常
Redission中的”attempt to unlock lock, not locked by current thread by node id

解决方案

方案一:

lock.lock(leaseTime, Unit)设置参数,即lock.lock()才能触发启动Redission的“看门狗机制守护线程
否则若设置参数,则到期就释放掉锁。

因为:
RedissonWatch Dog看门狗机制只会在显式设置最大持锁时间才会生效。换言之,一旦调用lock方法指定了leaseTime参数值,则该锁到期后即会自动释放。Redisson的Watch Dog看门狗不会对该锁进行自动续期
 

补充说明

  1. 我们显式设置Config类的lockWatchdogTimeout字段值时,使用默认的30秒。此时如果加锁时未显式设置最大持锁时间,即Watch Dog看门狗机制会生效的场景中。该锁实际上一开始也会设置一个默认最大持锁时间,即30秒。然后看门狗每隔10秒(30秒 * 1/3 = 10秒)会将该锁的最大持锁时间再次设置为30秒,以达到自动续期的目的。这样只要持锁线程业务还未执行完,则该锁就一直有效、不会被自动释放。当然一旦持锁的服务实例发生宕机后,看门狗的定时任务自然也无法续期。这样锁到期后也就释放掉了,避免了死锁的发生

方案二:

1. 使用lock.tryLock()替换lock.lock(),不停的尝试解锁
2. 同时finally添加代码`if (lock.isLocked && lock.isHeldByCurrentThread())`,先判断是否存在、若存在判断持有锁的是否是当前线程,则才能执行解锁操作
这样就避免了
当前线程业务执行完毕(即锁不存在了,锁存在则看门狗会定时帮着续期)且锁过期释放了(锁已经不存在了),
然后代码走到了finally执行unlock(),导致执行二次释放锁。导致报错attempt unlock ..企图解锁)。(锁已经不存在了,还解什么锁!当然报错喽~
别的线程tryLock()没获取到锁之后,
然后代码也是会走到了finally执行unlock(),导致的报错

RLock lock = redissonClient.getLock(SHUI_WEN_ST_PPTN_R_QUEUE);//参数是给锁起个名字name,不要重复
try {
    // 尝试抢获取锁,等待10秒(没抢到就算了,不循环抢),锁自动释放时间expire_time为30秒
    boolean isGetLocked = lock.tryLock(10, 30, TimeUnit.SECONDS);//也可以只传两个参数(等待时间和单位,默认expire_time为30秒)
    if (isGetLocked) {
        // 执行需要保护的“业务”代码
        ...
        ...
    } else {
    	// 未获得锁,处理锁定失败的情况
        log.info("抢锁失败");
    }
} catch (InterruptedException e) {
    // 处理中断异常
    log.error("系统异常",e);
    Thread.currentThread().interrupt();
} finally {
    // 解锁前检查当前线程是否持有该锁
    if (lock.isLocked && lock.isHeldByCurrentThread()) {
        lock.unlock();
        log.info("解锁成功");
    }
}


如下文章作者表示感谢!参考自:

分布式锁(三):基于Redisson的分布式锁实践 – 知乎 (zhihu.com)

Redission 解锁异常:attempt to unlock lock, not locked by current thread by node id_ℳ₯㎕ddzོꦿ࿐的博客-CSDN博客

redission分布式锁释放异常问题 – 简书 (jianshu.com) 

 

原文地址:https://blog.csdn.net/HD243608836/article/details/134194370

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_40852.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注