spring-projects / spring-projects/spring-data-redis

RedisTemplate.execute doesn't allow to specify action type and treats operation type as "read" by default

Open
#2,617 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

type: enhancement
Dominant language
Java
Stars
1.9k
Forks
1.3k
PR merge metrics
No merged PRs in 30d

Description

Hi!
I'm using a master/replica scheme with "read from replica" client property enabled.

var masterReplicaConfiguration =  new RedisStaticMasterReplicaConfiguration(masterNode.getHost(), masterNode.getPort());
redisProperties
    .getReplicas()
    .forEach(
        replica -> {
          RedisNode node = RedisNode.fromString(replica.getHost());
          masterReplicaConfiguration.addNode(node.getHost(), node.getPort());
        });

LettuceClientConfiguration.LettuceClientConfigurationBuilder clientConfigBuilder =
    LettuceClientConfiguration.builder().readFrom(ReadFrom.REPLICA_PREFERRED);

And I've tried to use custom distributed lock implementation, which is based on Redis scripts, like

private static final String LOCK_SCRIPT = "return redis.call('SET', KEYS[1], ARGV[1], 'PX', tonumber(ARGV[2]), 'NX') and true or false";

@Override
protected String acquire(final String key, final String storeId, final String token, final long expiration) {
  final List<String> singletonKeyList = Collections.singletonList(storeId + ":" + key);
  final boolean locked = stringRedisTemplate.execute(lockScript, singletonKeyList, token, String.valueOf(expiration));
  ...
}

It seems that "execute" is treated as a read operation by default, so it throws:

Caused by: <#029e4a23> org.springframework.data.redis.RedisSystemException: Error in execution; nested exception is io.lettuce.core.RedisReadOnlyException: READONLY You can't write against a read only replica. script: 15df23044ffd4f2723d9689555be4a5cccac4154, on @user_script:1.
	at o.s.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:54)

Is it possible to expose any options when calling RedisTemplate.execute to flag the operation as READ_WRITE, such as with Redissons RScript.Mode?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at RedisTemplate.execute and trace how its operation type is selected when running the provided Redis script. Check the Lettuce master/replica routing behavior with ReadFrom.REPLICA_PREFERRED. Done means callers can flag script execution as READ_WRITE so the lock script runs against the master without the READONLY error.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, redis
Domain
backend, databases
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.