Fixed - Spring Cache `Cacheable(sync)` loads value multiple times for reactive types or completableFuture. #6257

pull/6262/head
Nikita Koksharov 3 months ago
parent 661c1a0cc5
commit 234ad75647

@ -555,6 +555,10 @@ public final class ServiceManager {
private final Random random = RandomXoshiro256PlusPlus.create();
public Long generateValue() {
return random.nextLong();
}
public String generateId() {
return ByteBufUtil.hexDump(generateIdArray());
}

@ -15,11 +15,13 @@
*/
package org.redisson.spring.cache;
import org.redisson.RedissonObject;
import org.redisson.api.RFuture;
import org.redisson.api.RLock;
import org.redisson.api.RMap;
import org.redisson.api.RMapCache;
import org.redisson.client.RedisException;
import org.redisson.connection.ServiceManager;
import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;
@ -176,12 +178,14 @@ public class RedissonCache implements Cache {
}
public <T> CompletableFuture<T> retrieve(Object key, Supplier<CompletableFuture<T>> valueLoader) {
long threadId = Thread.currentThread().getId();
return retrieve(key).thenCompose(v -> {
if (v != null) {
return CompletableFuture.completedFuture((T) v);
}
ServiceManager sm = ((RedissonObject) map).getServiceManager();
long threadId = sm.generateValue();
RLock lock = map.getLock(key);
return lock.lockAsync(threadId).thenCompose(rr -> {
return map.getAsync(key)

Loading…
Cancel
Save