Uploaded image for project: 'Spring Data Redis'
  1. Spring Data Redis
  2. DATAREDIS-341

Allow to group redis commands in multi / exec blocks without having to use a SessionCallback

    Details

    • Type: Improvement
    • Status: Closed
    • Priority: Minor
    • Resolution: Won't Fix
    • Affects Version/s: 1.3.2 (Dijkstra SR2), 1.3.4 (Dijkstra SR4)
    • Fix Version/s: None
    • Component/s: Core
    • Labels:
      None
    • Sprint:
      52 - Evans GA, 53 - Evans SR1, 54 - Fowler M1, 55 - Evans SR2, 56 - Fowler RC1, 56 - Fowler GA, 57 - Fowler Aftermath, 58 - Gosling M1, 59 - Evans / Fowler SR, Gosling RC1

      Description

      Currently it is not possible to group some commands within a multi / exec block with redisTemplate without using a SessionCallback since
      every command uses another connection. We should use a thread-bound connection here to make this possible.

      public void someMethod(){
      	
      	ListOperations<String, String> listOps = (ListOperations<String, String>) redisTemplate.opsForList();
      
      	redisTemplate.multi();
      
      	listOps.range("foo:pit", 0, -1);
      	listOps.range("foo:actual", 0, -1);
      	listOps.range("foo:predicted", 0, -1);
      
      	List<Object> results = redisTemplate.exec();
      	//...
      }
      

      Results in:

      Caused by: redis.clients.jedis.exceptions.JedisDataException: ERR EXEC without MULTI
      	at redis.clients.jedis.Protocol.processError(Protocol.java:104)
      	at redis.clients.jedis.Protocol.process(Protocol.java:122)
      	at redis.clients.jedis.Protocol.read(Protocol.java:191)
      	at redis.clients.jedis.Connection.getRawObjectMultiBulkReply(Connection.java:221)
      	at redis.clients.jedis.Connection.getObjectMultiBulkReply(Connection.java:227)
      	at redis.clients.jedis.Transaction.exec(Transaction.java:38)
      	at org.springframework.data.redis.connection.jedis.JedisConnection.exec(JedisConnection.java:723)
      

      Current workaround is to use a SessionCallback which uses an appropriately scoped redis connection.

      List<Object> results = redisTemplate.execute(new SessionCallback<List<Object>>() {
      
      	@Override
      	public <K, V> List<Object> execute(RedisOperations<K, V> operations) throws DataAccessException {
      
      		@SuppressWarnings("unchecked")
      		ListOperations<String, String> listOps = (ListOperations<String, String>) operations.opsForList();
      
      		operations.multi();
      
      		listOps.range("foo:pit", 0, -1);
      		listOps.range("foo:actual", 0, -1);
      		listOps.range("foo:predicted", 0, -1);
      		
      		
      		return operations.exec();
      	}
      });
      

        Attachments

          Activity

            People

            • Assignee:
              mp911de Mark Paluch
              Reporter:
              thomasd Thomas Darimont
              Last updater:
              Mark Paluch
            • Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: