Redission Rlock线上出现的bug以及正确的使用
官网写法
个人解毒(读)
Redission
方法 | 效果 |
---|---|
lock() | 经典面试问题:如果业务执行未完成,锁释放了肿么办? lock()会默认使用一个看门狗的机制去延长锁的时间,默认30秒 |
lock(long leaseTime, TimeUnit unit) | 加锁leaseTime时间过后会自动解锁。 这里有个问题,很多人习惯lock(xx,xx)之后再次unlock(), 这里就有个坑了,下面再详细讲解 |
tryLock(long waitTime, long leaseTime, TimeUnit unit) | 最多等待waitTime,上锁之后leaseTime自动解锁 |
存在的坑
在我们不了解业务会执行多久的时候,使用lock(long leaseTime, TimeUnit unit),就会出现当我业务已经超过锁的时间之后,自动释放锁,这个时候你又去unlock(),会报IllegalMonitorStateException,也就是当前的锁已经不是你的了,你没有权限去解锁。
跳坑:我们在unlock的时候调用isHeldByCurrentThread()来判断是否被当前线程占有锁,然后再unlock().
思考
当出现上面的情况时,就是业务还没执行完,锁已经释放了。那这个分布式锁就废掉了,为啥?
当A拿到锁,开心的执行的时候,锁超时释放了。但是A还是认为自己拿到锁的,继续开心执行。这时B进来了,拿到锁。那么A和B都拿到锁了,这个分布式锁的意义就不存在了。
引申出其他的问题:我看到我们公司项目的代码,里面锁的是10秒,10秒哦,还报IllegalMonitorStateException错误,可以猜测这业务执行得有多慢,得优化。其次锁的粒度也没有控制好,他们把整个业务都包在锁里头。真正需要锁的可能就一小部分业务逻辑,西西~
最后
写法不规范,接坑人两行泪