diff --git a/redisson/src/main/java/org/redisson/RedissonWriteLock.java b/redisson/src/main/java/org/redisson/RedissonWriteLock.java index 865189236..c5e9b709f 100644 --- a/redisson/src/main/java/org/redisson/RedissonWriteLock.java +++ b/redisson/src/main/java/org/redisson/RedissonWriteLock.java @@ -68,13 +68,15 @@ public class RedissonWriteLock extends RedissonLock implements RLock { "end; " + "if (mode == 'write') then " + "if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " + - "redis.call('hincrby', KEYS[1], ARGV[2], 1); " + - "redis.call('pexpire', KEYS[1], ARGV[1]); " + + "redis.call('hincrby', KEYS[1], ARGV[2], 1); " + + "local currentExpire = redis.call('pttl', KEYS[1]); " + + "redis.call('pexpire', KEYS[1], currentExpire + ARGV[1]); " + "return nil; " + "end; " + "end;" + "return redis.call('pttl', KEYS[1]);", - Arrays.asList(getName()), internalLockLeaseTime, getLockName(threadId)); + Arrays.asList(getName()), + internalLockLeaseTime, getLockName(threadId)); } @Override @@ -108,7 +110,8 @@ public class RedissonWriteLock extends RedissonLock implements RLock { "end; " + "end; " + "return nil;", - Arrays.asList(getName(), getChannelName()), LockPubSub.unlockMessage, internalLockLeaseTime, getLockName(threadId)); + Arrays.asList(getName(), getChannelName()), + LockPubSub.unlockMessage, internalLockLeaseTime, getLockName(threadId)); } @Override diff --git a/redisson/src/test/java/org/redisson/RedissonReadWriteLockTest.java b/redisson/src/test/java/org/redisson/RedissonReadWriteLockTest.java index 1747afb78..893492134 100644 --- a/redisson/src/test/java/org/redisson/RedissonReadWriteLockTest.java +++ b/redisson/src/test/java/org/redisson/RedissonReadWriteLockTest.java @@ -19,9 +19,30 @@ import org.redisson.api.RedissonClient; import org.redisson.config.Config; import com.jayway.awaitility.Awaitility; +import com.jayway.awaitility.Duration; public class RedissonReadWriteLockTest extends BaseConcurrentTest { + @Test + public void testWriteLockExpiration() throws InterruptedException { + RReadWriteLock rw1 = redisson.getReadWriteLock("test2s3"); + + RLock l1 = rw1.writeLock(); + assertThat(l1.tryLock(10000, 10000, TimeUnit.MILLISECONDS)).isTrue(); + RLock l2 = rw1.writeLock(); + assertThat(l2.tryLock(1000, 1000, TimeUnit.MILLISECONDS)).isTrue(); + + Awaitility.await().atMost(Duration.TEN_SECONDS).until(() -> { + RReadWriteLock rw2 = redisson.getReadWriteLock("test2s3"); + try { + return !rw2.writeLock().tryLock(3000, 1000, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + e.printStackTrace(); + return false; + } + }); + } + @Test public void testInCluster() throws Exception { RedisRunner master1 = new RedisRunner().randomPort().randomDir().nosave();