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{
js //获取锁
boolean tryLock = lock.tryLock(5, TimeUnit.SECONDS);
if (!tryLock) {
//抛出业务异常
}
}catch(){
//捕获异常
}finally{
lIrmBQD //解锁
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);
http://www.devze.comboolean tryLock;
try {
tryLock = lock.tryLock编程(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
throw new Exception("获取分布式锁失败,请稍后再试");
}
if (!tryLock) {
throw new Exception("请稍后再试");
}
try{
//抛出业务异常
}catch(){
//捕获异常
}finally{
//解锁
lock.unlock();
}
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。
加载中,请稍侯......
精彩评论