今天在测试spring Redis的时候出现这么个:
org.springframework.dao.InvalidDataAccessApiUsageException: ERR EXEC without MULTI; nested exception is redis.clients.jedis.exceptions.JedisDataException: ERR EXEC without MULTI
另外还报: java.lang.NullPointerException
先记录下, http://stackoverflow.com/questions/11148383/how-to-implement-redis-multi-exec-by-using-spring-data-redis All Spring Configuration is written properly. Non-Multi-Exec Redis operations work perfectly. @Autowired @Qualifier("stringRedisTemplate") StringRedisTemplate template; void test(){ template.multi(); template.boundValueOps("somevkey").increment(1); template.boundZSetOps("somezkey").add("zvalue", timestamp); template.exec(); } After running above code through Junit Test, Exceptions are thrown. Unknown exception; nested exception is org.springframework.data.redis.RedisSystemException: Unknown jedis exception; nested exception is java.lang.NullPointerException The reason for the exception is probably that the Spring template implementation does not reuse the same connection for .multi() and .exec(). You can try to use execute() via a callback: private RedisTemplate template = ...; template.execute( new RedisCallback() { @Override public Object doInRedis(RedisConnection connection) throws DataAccessException { connection.multi(); //do whatever you need, like deleting and repopulating some keys connection.expire(CHANNEL_KEY.getBytes(), EXPIRE_SECS); connection.exec(); return null; });
先记录下,希望明天去公司能搞定 http://forum.springsource.org/archive/index.php/t-125387.html Hello! I am getting very many exceptions and strange results using redisTemplate and it's callbacks. Problems we spotted in:
Multi-Discard using RedisCallback Multi-Exec using RedisCallback Watch-Multi-Exec using RedisCallback Multi-Exec in pipelined RedisCallback Watch-Multi-Unwatch-Exec using RedisCallback Also two bugs we spotted and added to JIRA: DATAREDIS-87, DATAREDIS-88 For some reason I was not able to attach file with code. Will email it on demand. Sample:
@Test public void testMultiDiscard1() throws Exception { redisTemplate.execute(new RedisCallback<Object>() { @Override public Object doInRedis(RedisConnection connection) throws DataAccessException { connection.set("a".getBytes(), "b".getBytes()); assertEquals(1, redisTemplate.keys("a").size()); connection.multi(); assertEquals(1, redisTemplate.keys("a").size()); connection.set("a".getBytes(), "bbb".getBytes()); connection.append("a".getBytes(), "ccc".getBytes()); connection.hSet("a1".getBytes(), "field1".getBytes(), "1000".getBytes()); connection.hIncrBy("a1".getBytes(), "field1".getBytes(), 10); Map<byte[], byte[]> args = new HashMap<byte[], byte[]>(3); args.put("field2".getBytes(), "valueX".getBytes()); args.put("field3".getBytes(), "valueY".getBytes()); args.put("field4".getBytes(), "000".getBytes()); connection.hMSet("a2".getBytes(), args); connection.append("a3".getBytes(), "bunny".getBytes()); assertEquals(1, redisTemplate.keys("a").size()); assertTrue(redisTemplate.keys("a1").isEmpty()); connection.discard(); return null; } }, true); assertNotNull(redisTemplate.opsForValue().get("a")); assertTrue(redisTemplate.opsForHash().values("a1").isEmpty()); }
I was working on a redis mock to be able to test without real redis. When run the tests on real one quite a big number of them failed, but shouldn't (as for me). Maybe I'm doing smth wrong? Thanks in advance!
Building Applications with Spring Data Redis http://www.packtpub.com/article/building-applications-spring-data-redis