问题
redission解锁异常:
Redission中的”attempt to unlock lock, not locked by current thread by node id“
解决方案
方案一:
lock.lock(leaseTime, Unit)不设置参数,即lock.lock(),才能触发启动Redission的“看门狗”机制(守护线程)。
否则若设置了参数,则到期就释放掉锁。
因为:
Redisson的Watch Dog看门狗机制只会在未显式设置最大持锁时间才会生效。换言之,一旦调用lock方法时指定了leaseTime参数值,则该锁到期后即会自动释放。Redisson的Watch Dog看门狗不会对该锁进行自动续期
补充说明:
方案二:
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进行投诉反馈,一经查实,立即删除!