redisson 的 watchdog 有一个自动延期的机制,是说,比如业务估计耗时 30s ,我设置了 30s ,极端情况执行如果超过 30s ,锁释放了,会出错,所以在到达 30s 的时候 redisson 如果发现任务没有执行完会自动续期直到任务结束释放锁,大概是这么个意思。
实际开发中:
// 具有 Watch Dog 自动延期机制 默认续 30s 每隔 30/3=10 秒续到 30s
lock.lock();
// 尝试拿锁 10s 后停止重试,返回 false 具有 Watch Dog 自动延期机制 默认续 30s
boolean res1 = lock.tryLock(10, TimeUnit.SECONDS);
1
pannanxu 2022-02-14 15:01:04 +08:00
try ... finally ...
finally 里释放锁就好了,宕机了,redis 设置过超时时间,不用管;死循应该考虑代码写的是否有问题 |
2
keshawnvan 2022-02-14 15:06:26 +08:00
所以业务上最好是用 tryLock 而不是 lock
|
3
Chinsung 2022-02-14 17:19:39 +08:00
这种都是要看取舍的。
首先,你描述的这种情况,并不是死锁,因为并没有互相等待对方持有的资源。watchdog 不释放,唯一的情况也就是其他后续的线程一直去争抢和尝试获取这个锁,但是这里 redisson 还有优化,用了 redis 的订阅机制来解决,后续到达的线程都会直接挂起自己等待订阅机制来唤醒。 如果死循环的话,上游或者下游一般总有一个会触发超时机制,无非是时间可能会比想象的要长非常多罢了。 宕机的话,redisson 续约的线程也会宕机,就不会触发续约,其他机器就能拿到这个锁,所以也不存在问题。 说到底,你是用这个机制的本意就是希望“锁不要在任务没有执行完之前就释放”,然后反而又要求“万一永远执行不完,还是要释放掉”。最终的考虑就是在这 2 种情况间,哪种情况出现的后果更麻烦,你就选择解决对应问题的方案 |
4
cheng6563 2022-02-14 17:36:28 +08:00
锁就是这样用的啊,你不释放,他就一直占着。如果他后台偷偷自己释放了才是要命。
死循环你得自己设置个退出机制,不然就算不用锁他也是个死循环。 宕机了你服务就不可用了吧,那他就会自己超时释放了,你还可以搞个守护进程之类的把服务 kill 掉重启。 这不叫死锁,死锁指的是 A 等待 B 解锁,B 等待 A 解锁,造成相互一直等下去。 |
5
giantreaper0 2023-04-20 10:18:33 +08:00
即使你用本地锁 synchronized 业务代码有 bug 导致死循环那也是这样子的呀
|