Fixed expiration handling of reentrant write lock. #1110

pull/1124/head
Nikita 7 years ago
parent 48ea96f2fe
commit cbda17c682

@ -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.<Object>asList(getName()), internalLockLeaseTime, getLockName(threadId));
Arrays.<Object>asList(getName()),
internalLockLeaseTime, getLockName(threadId));
}
@Override
@ -108,7 +110,8 @@ public class RedissonWriteLock extends RedissonLock implements RLock {
"end; " +
"end; "
+ "return nil;",
Arrays.<Object>asList(getName(), getChannelName()), LockPubSub.unlockMessage, internalLockLeaseTime, getLockName(threadId));
Arrays.<Object>asList(getName(), getChannelName()),
LockPubSub.unlockMessage, internalLockLeaseTime, getLockName(threadId));
}
@Override

@ -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();

Loading…
Cancel
Save