2012-06-21 10 views
6

모든 Spring 구성이 올바르게 작성됩니다. Non-Multi-Exec Redis 작업은 완벽하게 작동합니다.Spring-data-Redis를 사용하여 Redis Multi-Exec을 구현하는 방법

@Autowired 
@Qualifier("stringRedisTemplate") 
StringRedisTemplate template; 

void test(){ 
    template.multi(); 
    template.boundValueOps("somevkey").increment(1); 
    template.boundZSetOps("somezkey").add("zvalue", timestamp); 
    template.exec(); 
} 

위의 코드를 Junit 테스트를 통해 실행 한 후에 예외가 발생합니다.

org.springframework.data.redis.RedisSystemException: Unknown exception; nested exception is org.springframework.data.redis.RedisSystemException: Unknown jedis exception; nested exception is java.lang.NullPointerException 
     at org.springframework.data.redis.connection.jedis.JedisUtils.convertJedisAccessException(JedisUtils.java:93) 
     at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.translateExceptionIfPossible(JedisConnectionFactory.java:155) 
     at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:58) 
     at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213) 
     at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:163) 
     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) 
     at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) 
     at $Proxy66.appendUserStream(Unknown Source) 
     at com.uniu.test.repository.StreamCacheRepositoryTest.testAppendUserStream(StreamCacheRepositoryTest.java:23) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
     at java.lang.reflect.Method.invoke(Method.java:597) 
     at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 
     at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
     at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 
     at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 
     at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) 
     at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74) 
     at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83) 
     at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72) 
     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) 
     at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) 
     at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) 
     at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) 
     at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 
     at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 
     at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) 
     at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 
     at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) 
     at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 
     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) 
     at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49) 
     at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 
    Caused by: org.springframework.data.redis.RedisSystemException: Unknown jedis exception; nested exception is java.lang.NullPointerException 
     at org.springframework.data.redis.connection.jedis.JedisConnection.convertJedisAccessException(JedisConnection.java:119) 
     at org.springframework.data.redis.connection.jedis.JedisConnection.exec(JedisConnection.java:523) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
     at java.lang.reflect.Method.invoke(Method.java:597) 
     at org.springframework.data.redis.core.CloseSuppressingInvocationHandler.invoke(CloseSuppressingInvocationHandler.java:58) 
     at $Proxy70.exec(Unknown Source) 
     at org.springframework.data.redis.core.RedisTemplate$1.doInRedis(RedisTemplate.java:416) 
     at org.springframework.data.redis.core.RedisTemplate$1.doInRedis(RedisTemplate.java:412) 
     at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:162) 
     at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:133) 
     at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:121) 
     at org.springframework.data.redis.core.RedisTemplate.exec(RedisTemplate.java:412) 
     at com.uniu.repository.impl.StreamCacheRepositoryRedisImpl.appendUserStream(StreamCacheRepositoryRedisImpl.java:37) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
     at java.lang.reflect.Method.invoke(Method.java:597) 
     at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318) 
     at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183) 
     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) 
     at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155) 
     ... 33 more 
    Caused by: java.lang.NullPointerException 
     at redis.clients.jedis.BinaryTransaction.exec(BinaryTransaction.java:31) 
     at org.springframework.data.redis.connection.jedis.JedisConnection.exec(JedisConnection.java:521) 
     ... 54 more 

redis 서버를 확인하면 위의 두 명령이 실행되어 결과가 정확합니다. 그래서 문제는 코드의 마지막 줄에 있습니다 (template.exec()). 기본 JedisClient가 EXEC에서 다중 응답을 얻으려고 할 때 NullPointerException이 발생합니다.

spring-data-redis 1.0.0.RELEASE를 사용합니다. 도움을 주셔서 감사합니다.

답변

8

예외 이유는 아마도 Spring 템플릿 구현이 .multi().exec()에 대해 동일한 연결을 다시 사용하지 않기 때문일 수 있습니다. execute()을 콜백을 통해 사용할 수 있습니다.

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; 
    } 

    } 

); 
+0

을 활성화 할 수 있습니다. multi와 exec가 같은 팩토리를 통해 호출되고 트랜잭션이 활성화되어있는 한 그 사이의 모든 호출은 동일한 연결을 사용합니다. RedisConnectionUtils에서 볼 수 있습니다. – Olayinka

5
template.setEnableTransactionSupport(true); 

어쩌면 당신은 사용자 이것은 내가 이것이 사실 생각하지 않는다 거래를

관련 문제