3232import org .springframework .data .redis .connection .ReactiveStringCommands ;
3333import org .springframework .data .redis .connection .RedisConnection ;
3434import org .springframework .data .redis .connection .RedisConnectionFactory ;
35+ import org .springframework .data .redis .connection .RedisStringCommands ;
3536import org .springframework .data .redis .connection .RedisStringCommands .SetOption ;
3637import org .springframework .data .redis .core .types .Expiration ;
3738import org .springframework .data .redis .util .ByteUtils ;
@@ -219,8 +220,10 @@ public byte[] putIfAbsent(String name, byte[] key, byte[] value, @Nullable Durat
219220
220221 return execute (name , connection -> {
221222
223+ boolean wasLocked = false ;
222224 if (isLockingCacheWriter ()) {
223225 doLock (name , key , value , connection );
226+ wasLocked = true ;
224227 }
225228
226229 try {
@@ -242,7 +245,7 @@ public byte[] putIfAbsent(String name, byte[] key, byte[] value, @Nullable Durat
242245 return connection .stringCommands ().get (key );
243246
244247 } finally {
245- if (isLockingCacheWriter ()) {
248+ if (isLockingCacheWriter () && wasLocked ) {
246249 doUnlock (name , connection );
247250 }
248251 }
@@ -319,15 +322,17 @@ void lock(String name) {
319322 execute (name , connection -> doLock (name , name , null , connection ));
320323 }
321324
322- @ Nullable
323- protected Boolean doLock (String name , Object contextualKey , @ Nullable Object contextualValue ,
324- RedisConnection connection ) {
325+ boolean doLock (String name , Object contextualKey , @ Nullable Object contextualValue , RedisConnection connection ) {
325326
327+ RedisStringCommands commands = connection .stringCommands ();
326328 Expiration expiration = Expiration .from (this .lockTtl .getTimeToLive (contextualKey , contextualValue ));
329+ byte [] cacheLockKey = createCacheLockKey (name );
327330
328- while (!ObjectUtils .nullSafeEquals (connection .stringCommands ().set (createCacheLockKey (name ), new byte [0 ], expiration , SetOption .SET_IF_ABSENT ),true )) {
331+ while (!ObjectUtils .nullSafeEquals (commands .set (cacheLockKey , new byte [0 ], expiration , SetOption .SET_IF_ABSENT ),
332+ true )) {
329333 checkAndPotentiallyWaitUntilUnlocked (name , connection );
330334 }
335+
331336 return true ;
332337 }
333338
@@ -341,7 +346,7 @@ void unlock(String name) {
341346 }
342347
343348 @ Nullable
344- private Long doUnlock (String name , RedisConnection connection ) {
349+ Long doUnlock (String name , RedisConnection connection ) {
345350 return connection .keyCommands ().del (createCacheLockKey (name ));
346351 }
347352
@@ -489,8 +494,7 @@ public CompletableFuture<byte[]> retrieve(String name, byte[] key, @Nullable Dur
489494 Mono <?> cacheLockCheck = isLockingCacheWriter () ? waitForLock (connection , name ) : Mono .empty ();
490495 ReactiveStringCommands stringCommands = connection .stringCommands ();
491496
492- Mono <ByteBuffer > get = shouldExpireWithin (ttl )
493- ? stringCommands .getEx (wrappedKey , Expiration .from (ttl ))
497+ Mono <ByteBuffer > get = shouldExpireWithin (ttl ) ? stringCommands .getEx (wrappedKey , Expiration .from (ttl ))
494498 : stringCommands .get (wrappedKey );
495499
496500 return cacheLockCheck .then (get ).map (ByteUtils ::getBytes ).toFuture ();
@@ -502,8 +506,7 @@ public CompletableFuture<Void> store(String name, byte[] key, byte[] value, @Nul
502506
503507 return doWithConnection (connection -> {
504508
505- Mono <?> mono = isLockingCacheWriter ()
506- ? doStoreWithLocking (name , key , value , ttl , connection )
509+ Mono <?> mono = isLockingCacheWriter () ? doStoreWithLocking (name , key , value , ttl , connection )
507510 : doStore (key , value , ttl , connection );
508511
509512 return mono .then ().toFuture ();
@@ -531,7 +534,6 @@ private Mono<Boolean> doStore(byte[] cacheKey, byte[] value, @Nullable Duration
531534 }
532535 }
533536
534-
535537 private Mono <Object > doLock (String name , Object contextualKey , @ Nullable Object contextualValue ,
536538 ReactiveRedisConnection connection ) {
537539
0 commit comments