Spring Integration 分布式锁:与 Redisson 的租用时间相比,TTL 概念上的一致性

问题描述 投票:0回答:1

这是以下问题的后续问题:https://github.com/spring-projects/spring-integration/issues/8687

正如上面链接中所讨论的,Spring Integration Distributed Lock 的 TTL 概念仅适用于跨进程,不适用于同一进程中的线程。

后来尝试了redisson,它的RLock中有一个租约时间的概念:


    /**
     * Tries to acquire the lock with defined <code>leaseTime</code>.
     * Waits up to defined <code>waitTime</code> if necessary until the lock became available.
     *
     * Lock will be released automatically after defined <code>leaseTime</code> interval.
     *
     * @param waitTime the maximum time to acquire the lock
     * @param leaseTime lease time
     * @param unit time unit
     * @return <code>true</code> if lock is successfully acquired,
     *          otherwise <code>false</code> if lock is already set.
     * @throws InterruptedException - if the thread is interrupted
     */
    boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException;

https://github.com/redisson/redisson/blob/c2c00a07c279d55d627717fbb290426e19744a65/redisson/src/main/java/org/redisson/api/RLock.java#L55

我认为TTL和租约时间这两个概念很相似(如果我错了请纠正我)。

但是,redisson 的租用时间对于跨进程同一进程中的线程都以一致的方式工作,而 spring 集成的TTL不是

下面的junit测试可以重现我的意思: https://github.com/cuipengfei/Spikes/blob/22a9896137dd62bda5f030f5a3d33c67fba67310/jpa/spring-jdbc-distributed-lock-issue/src/test/java/com/github/spring/example/LockTest.java#L38C9-L49

docker run -p 6379:6379 -d redis:7.0.12 --requirepass "mypass"

docker run -e POSTGRES_USER=localtest -e POSTGRES_PASSWORD=localtest -e POSTGRES_DB=orders -p 5432:5432 -d postgres:15.3

# start this docker container before running the above junit test

并更改模式进行比较:https://github.com/cuipengfei/Spikes/blob/master/jpa/spring-jdbc-distributed-lock-issue/src/test/resources/application.properties#L16-L17

lock.registry.name=redisson
# change this line to redis / jdbc / redisson then run test

在spring集成的redis/jdbc模式下运行测试时,线程2经过ttl后也拿不到锁

在redisson模式下运行测试时,线程2可以在租约时间过去后获得锁,我认为这在概念上更有意义。

并不是想说哪个更好,只是出于好奇,与Redisson的租约时间相比,Spring Integration的ttl工作原理是否有特殊原因?

java spring-integration redisson distributed-lock spring-integration-distributed-lock
1个回答
0
投票

那个

RLock.tryLock()
的 Javadoc 是错误的,它使用
leaseTime
来解释
waitTime
。我相信可能还有其他不同的方法来实现分布式锁。

如果你查看 Spring Integration 的

RedisLockRegistry
,你会发现它与
JdbcLockRegistry
类似,并且有一个带有
ReentrantLock
的本地守卫。因此,同一进程内的所有交互都遵循标准 Java
Lock
算法。正如我在该问题中向您解释的那样:
TTL
实际上是为了在分布式环境中解除死锁。另一方面,您无法预测进程将持有锁多长时间,因此由于某些原因而过早释放锁可能会导致系统中您期望受到锁保护的不一致。
不确定您进行此锁定练习的目标是什么,但我认为您的问题属于 

leaseTime

类别,必须从 SO 中删除。

    

© www.soinside.com 2019 - 2024. All rights reserved.