Fixed - transactional Map and MapCache keySet method returns inconsistent state.

pull/5477/merge
Nikita Koksharov 1 year ago
parent cb8531d447
commit 7265dbe93a

@ -615,7 +615,24 @@ public class BaseTransactionalMap<K, V> extends BaseTransactionalObject {
}); });
return new CompletableFutureWrapper<>(f); return new CompletableFutureWrapper<>(f);
} }
protected Set<K> keySet(String pattern, int count) {
Set<K> keys = map.keySet(pattern, count);
return keys.stream()
.map(k -> Collections.singletonMap(k, toKeyHash(k)))
.filter(k -> {
HashValue hash = k.values().iterator().next();
if (state.get(hash) == null
|| state.get(hash) != BaseTransactionalMap.MapEntry.NULL) {
return true;
}
return false;
})
.map(m -> m.keySet().iterator().next())
.collect(Collectors.toSet());
}
protected RFuture<V> removeOperationAsync(K key) { protected RFuture<V> removeOperationAsync(K key) {
long threadId = Thread.currentThread().getId(); long threadId = Thread.currentThread().getId();
return executeLocked(key, () -> { return executeLocked(key, () -> {

@ -211,7 +211,13 @@ public class RedissonTransactionalMap<K, V> extends RedissonMap<K, V> {
checkState(); checkState();
return transactionalMap.removeOperationAsync(key); return transactionalMap.removeOperationAsync(key);
} }
@Override
public Set<K> keySet(String pattern, int count) {
checkState();
return transactionalMap.keySet(pattern, count);
}
@Override @Override
protected RFuture<Boolean> removeOperationAsync(Object key, Object value) { protected RFuture<Boolean> removeOperationAsync(Object key, Object value) {
checkState(); checkState();

@ -332,4 +332,10 @@ public class RedissonTransactionalMapCache<K, V> extends RedissonMapCache<K, V>
throw new UnsupportedOperationException("getReadWriteLock method is not supported in transaction"); throw new UnsupportedOperationException("getReadWriteLock method is not supported in transaction");
} }
@Override
public Set<K> keySet(String pattern, int count) {
checkState();
return transactionalMap.keySet(pattern, count);
}
} }

@ -2,7 +2,7 @@ package org.redisson.transaction;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.redisson.BaseTest; import org.redisson.RedisDockerTest;
import org.redisson.api.RMap; import org.redisson.api.RMap;
import org.redisson.api.RTransaction; import org.redisson.api.RTransaction;
import org.redisson.api.TransactionOptions; import org.redisson.api.TransactionOptions;
@ -17,7 +17,7 @@ import java.util.concurrent.TimeUnit;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
public abstract class RedissonBaseTransactionalMapTest extends BaseTest { public abstract class RedissonBaseTransactionalMapTest extends RedisDockerTest {
protected abstract RMap<String, String> getMap(); protected abstract RMap<String, String> getMap();

@ -14,13 +14,13 @@ import static org.assertj.core.api.Assertions.assertThat;
public class RedissonTransactionalMapCacheTest extends RedissonBaseTransactionalMapTest { public class RedissonTransactionalMapCacheTest extends RedissonBaseTransactionalMapTest {
@Test @Test
public void testSyncWait() throws IOException, InterruptedException { public void testSyncWait() {
String mapCacheName = "map"; String mapCacheName = "map";
String dataKey = "key"; String dataKey = "key";
Config redisConfig = new Config(); Config redisConfig = new Config();
redisConfig.useReplicatedServers() redisConfig.useReplicatedServers()
.addNodeAddress(RedisRunner.getDefaultRedisServerBindAddressAndPort()); .addNodeAddress(redisson.getConfig().useSingleServer().getAddress());
RedissonClient client = Redisson.create(redisConfig); RedissonClient client = Redisson.create(redisConfig);
RTransaction transaction = client.createTransaction(TransactionOptions.defaults()); RTransaction transaction = client.createTransaction(TransactionOptions.defaults());

Loading…
Cancel
Save