diff --git a/redisson/src/main/java/org/redisson/transaction/RedissonTransaction.java b/redisson/src/main/java/org/redisson/transaction/RedissonTransaction.java index ba8e9e2bb..c5aa6cfab 100644 --- a/redisson/src/main/java/org/redisson/transaction/RedissonTransaction.java +++ b/redisson/src/main/java/org/redisson/transaction/RedissonTransaction.java @@ -54,6 +54,11 @@ public class RedissonTransaction implements RTransaction { private final TransactionOptions options; private List operations = new CopyOnWriteArrayList<>(); private Set localCaches = new HashSet<>(); + private final Map, RLocalCachedMap> localCacheInstances = new HashMap<>(); + private final Map instances = new HashMap<>(); + + private RedissonTransactionalBuckets bucketsInstance; + private RedissonTransactionalBuckets bucketsCodecInstance; private final long startTime = System.currentTimeMillis(); private final String id = generateId(); @@ -78,92 +83,120 @@ public class RedissonTransaction implements RTransaction { checkState(); localCaches.add(fromInstance.getName()); - return new RedissonTransactionalLocalCachedMap(commandExecutor, - operations, options.getTimeout(), executed, fromInstance, id); + return (RLocalCachedMap) localCacheInstances.computeIfAbsent(fromInstance, k -> { + return new RedissonTransactionalLocalCachedMap<>(commandExecutor, + operations, options.getTimeout(), executed, fromInstance, id); + }); } @Override public RBucket getBucket(String name) { checkState(); - - return new RedissonTransactionalBucket(commandExecutor, options.getTimeout(), name, operations, executed, id); + + return (RBucket) instances.computeIfAbsent(name, k -> { + return new RedissonTransactionalBucket(commandExecutor, options.getTimeout(), name, operations, executed, id); + }); } @Override public RBucket getBucket(String name, Codec codec) { checkState(); - return new RedissonTransactionalBucket(codec, commandExecutor, options.getTimeout(), name, operations, executed, id); + return (RBucket) instances.computeIfAbsent(name, k -> { + return new RedissonTransactionalBucket(codec, commandExecutor, options.getTimeout(), name, operations, executed, id); + }); } @Override public RBuckets getBuckets() { checkState(); - - return new RedissonTransactionalBuckets(commandExecutor, options.getTimeout(), operations, executed, id); + + if (bucketsInstance == null) { + bucketsInstance = new RedissonTransactionalBuckets(commandExecutor, options.getTimeout(), operations, executed, id); + } + return bucketsInstance; } @Override public RBuckets getBuckets(Codec codec) { checkState(); - - return new RedissonTransactionalBuckets(codec, commandExecutor, options.getTimeout(), operations, executed, id); + + if (bucketsCodecInstance == null) { + bucketsCodecInstance = new RedissonTransactionalBuckets(codec, commandExecutor, options.getTimeout(), operations, executed, id); + } + return bucketsCodecInstance; } @Override public RSet getSet(String name) { checkState(); - - return new RedissonTransactionalSet(commandExecutor, name, operations, options.getTimeout(), executed, id); + + return (RSet) instances.computeIfAbsent(name, k -> { + return new RedissonTransactionalSet(commandExecutor, name, operations, options.getTimeout(), executed, id); + }); } @Override public RSet getSet(String name, Codec codec) { checkState(); - - return new RedissonTransactionalSet(codec, commandExecutor, name, operations, options.getTimeout(), executed, id); + + return (RSet) instances.computeIfAbsent(name, k -> { + return new RedissonTransactionalSet(codec, commandExecutor, name, operations, options.getTimeout(), executed, id); + }); } @Override public RSetCache getSetCache(String name) { checkState(); - - return new RedissonTransactionalSetCache(commandExecutor, name, operations, options.getTimeout(), executed, id); + + return (RSetCache) instances.computeIfAbsent(name, k -> { + return new RedissonTransactionalSetCache(commandExecutor, name, operations, options.getTimeout(), executed, id); + }); } @Override public RSetCache getSetCache(String name, Codec codec) { checkState(); - - return new RedissonTransactionalSetCache(codec, commandExecutor, name, operations, options.getTimeout(), executed, id); + + return (RSetCache) instances.computeIfAbsent(name, k -> { + return new RedissonTransactionalSetCache(codec, commandExecutor, name, operations, options.getTimeout(), executed, id); + }); } @Override public RMap getMap(String name) { checkState(); - - return new RedissonTransactionalMap(commandExecutor, name, operations, options.getTimeout(), executed, id); + + return (RMap) instances.computeIfAbsent(name, k -> { + return new RedissonTransactionalMap(commandExecutor, name, operations, options.getTimeout(), executed, id); + }); } @Override public RMap getMap(String name, Codec codec) { checkState(); - - return new RedissonTransactionalMap(codec, commandExecutor, name, operations, options.getTimeout(), executed, id); + + return (RMap) instances.computeIfAbsent(name, k -> { + return new RedissonTransactionalMap(codec, commandExecutor, name, operations, options.getTimeout(), executed, id); + }); } @Override public RMapCache getMapCache(String name) { checkState(); - - return new RedissonTransactionalMapCache(commandExecutor, name, operations, options.getTimeout(), executed, id); + + return (RMapCache) instances.computeIfAbsent(name, k -> { + return new RedissonTransactionalMapCache(commandExecutor, name, operations, options.getTimeout(), executed, id); + }); } @Override public RMapCache getMapCache(String name, Codec codec) { checkState(); - - return new RedissonTransactionalMapCache(codec, commandExecutor, name, operations, options.getTimeout(), executed, id); + + return (RMapCache) instances.computeIfAbsent(name, k -> { + return new RedissonTransactionalMapCache(codec, commandExecutor, name, operations, options.getTimeout(), executed, id); + }); } @Override