关于 redis 锁续期的问题?

关于 redis 锁续期的问题,锁超时机制和锁续期机制似乎是相斥的。
当一个持有锁的线程挂掉以后,如果使用了锁超时机制,可以防止死锁,但是无法解决过期时间太短,导致任务未执行完毕就解锁的问题。而如果使用了锁续期机制,可以解决过期时间太短的问题,但是无法防止死锁,锁将永远不会过期.

不知道我的理解对不对。


回答:

锁超时可以避免死锁,但是可能存在任务还未运行完,锁就过期了的情况,所以才引入了锁续期机制。

楼主这里说的 "当一个持有锁的线程挂掉以后,如果使用了锁超时机制,可以防止死锁,但是无法解决过期时间太短,导致任务未执行完毕就解锁的问题",后半句是有问题的,因为当持有锁的线程挂掉,说明任务已经执行异常了,这时候当锁到了过期时间后自动过期解锁是正常的

"而如果使用了锁续期机制,可以解决过期时间太短的问题,但是无法防止死锁,锁将永远不会过期",而这里其实并不会有死锁,锁续期是会另起一个线程(看门狗)来监听锁是否还被该线程所持有,如果是,才会续期,所以当线程执行完任务释放锁之后,就不会续期锁了,也就不会死锁

redisson部分源码如下

protected CompletionStage<Boolean> renewExpirationAsync(long threadId) {

return evalWriteAsync(getRawName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,

"if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " +

"redis.call('pexpire', KEYS[1], ARGV[1]); " +

"return 1; " +

"end; " +

"return 0;",

Collections.singletonList(getRawName()),

internalLockLeaseTime, getLockName(threadId));

}


回答:

“而如果使用了锁续期机制,可以解决过期时间太短的问题,但是无法防止死锁,锁将永远不会过期”。

如果你用了 Redisson,那么确实可能会存在这个问题 —— 即持有锁的线程在释放锁之前挂掉,但 Watchdog 并不知道、依然在不断地续期。

所以你要养成良好的编码习惯,持有锁的部分代码要 try-catch,finally 里去释放锁。

关于此问题,Redisson 的作者已经告诉你了,要自己去 catch 线程内部的异常
https://github.com/redisson/r...

如果你想问线程挂的连 finally 都不执行了怎么办 —— 这种情况下要么主线程也已经挂了,整个进程就宕掉了,那你也无所谓担心 Watchdog 了;要么这是个守护线程,确实依然有问题,不过一般你也不会特意去写守护线程、或者在守护线程里持有锁。否则无论是 RuntimeException 还是外部 interrupt() 掉这个线程了,都会执行 finally 的。

以上是 关于 redis 锁续期的问题? 的全部内容, 来源链接: utcz.com/p/944625.html

回到顶部