Skip to content

Commit eb6dead

Browse files
author
Michal Domagala
committed
Carefully switch from Redis unlink to delete
More performant `unlink` is not available on Redis 3. Implementation is aware that, however not careful exception handling may switch to less performant `delete` on connection exception or similar case. The switch is permanent. Maybe better choice is drop support for Redis 3, which is not maintained since 2018 Signed-off-by: Michal Domagala <[email protected]>
1 parent 964dd9f commit eb6dead

File tree

1 file changed

+21
-25
lines changed

1 file changed

+21
-25
lines changed

spring-integration-redis/src/main/java/org/springframework/integration/redis/util/RedisLockRegistry.java

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747

4848
import org.springframework.beans.factory.DisposableBean;
4949
import org.springframework.dao.CannotAcquireLockException;
50+
import org.springframework.dao.InvalidDataAccessApiUsageException;
51+
import org.springframework.data.redis.RedisSystemException;
5052
import org.springframework.data.redis.connection.Message;
5153
import org.springframework.data.redis.connection.MessageListener;
5254
import org.springframework.data.redis.connection.RedisConnectionFactory;
@@ -584,40 +586,34 @@ public final void unlock() {
584586

585587
private void removeLockKey() {
586588
if (RedisLockRegistry.this.unlinkAvailable) {
587-
Boolean unlinkResult = null;
588589
try {
589-
// Attempt to UNLINK the lock key; an exception indicates lack of UNLINK support
590-
unlinkResult = removeLockKeyInnerUnlink();
590+
boolean unlinkResult = removeLockKeyInnerUnlink();
591+
if (unlinkResult) {
592+
// Lock key successfully unlinked
593+
stopRenew();
594+
} else {
595+
throw new ConcurrentModificationException("Lock was released in the store due to expiration. " +
596+
"The integrity of data protected by this lock may have been compromised.");
597+
}
591598
}
592-
catch (Exception ex) {
599+
catch (InvalidDataAccessApiUsageException | RedisSystemException ex) {
600+
// Redis 3 or earlier lacks of UNLINK support
601+
// jedis throws InvalidDataAccessApiUsageException, lettuce RedisSystemException
602+
LOGGER.warn("The UNLINK command has failed (not supported on the Redis server?); " +
603+
"falling back to the regular DELETE command", ex);
593604
RedisLockRegistry.this.unlinkAvailable = false;
594-
if (LOGGER.isDebugEnabled()) {
595-
LOGGER.debug("The UNLINK command has failed (not supported on the Redis server?); " +
596-
"falling back to the regular DELETE command", ex);
597-
}
598-
else {
599-
LOGGER.warn("The UNLINK command has failed (not supported on the Redis server?); " +
600-
"falling back to the regular DELETE command: " + ex.getMessage());
601-
}
605+
removeLockKey(); // retry with delete branch
602606
}
603-
604-
if (Boolean.TRUE.equals(unlinkResult)) {
605-
// Lock key successfully unlinked
607+
} else {
608+
boolean deleteResult = removeLockKeyInnerDelete();
609+
if (deleteResult) {
610+
// Lock key successfully deleted
606611
stopRenew();
607-
return;
608-
}
609-
else if (Boolean.FALSE.equals(unlinkResult)) {
612+
} else {
610613
throw new ConcurrentModificationException("Lock was released in the store due to expiration. " +
611614
"The integrity of data protected by this lock may have been compromised.");
612615
}
613616
}
614-
if (!removeLockKeyInnerDelete()) {
615-
throw new ConcurrentModificationException("Lock was released in the store due to expiration. " +
616-
"The integrity of data protected by this lock may have been compromised.");
617-
}
618-
else {
619-
stopRenew();
620-
}
621617
}
622618

623619
protected final boolean renew(long expireAfter) {

0 commit comments

Comments
 (0)