복붙노트

[REDIS] 봄 - 데이터 - 레디 스를 사용하여 레디 스 멀티 Exec에서 구현하는 방법

REDIS

봄 - 데이터 - 레디 스를 사용하여 레디 스 멀티 Exec에서 구현하는 방법

모든 봄 구성이 제대로 기록됩니다. 비 멀티 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

나는 위의 두 명령이 실행되고, 레디 스 서버를 확인하고 올바른 결과입니다. 문제는 코드의 마지막 줄에 온다 그래서 (template.exec ()). JedisClient가 EXEC에서 multibulk 응답을 얻으려고 기본 때 NullPointerException이 던져 보인다

나는 봄 - 데이터 - 레디 스 사용 1.0.0.RELEASE을 도와 줘서 고마워.

해결법

  1. ==============================

    1.예외의 이유는 봄 템플릿 구현 .multi ()와 .exec에 대한 동일한 연결 ()을 다시 사용하지 않는 아마. 당신은 콜백을 통해 () 실행 사용하려고 할 수 있습니다 :

    예외의 이유는 봄 템플릿 구현 .multi ()와 .exec에 대한 동일한 연결 ()을 다시 사용하지 않는 아마. 당신은 콜백을 통해 () 실행 사용하려고 할 수 있습니다 :

    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;
        }
    
      }
    
    );
    
  2. ==============================

    2.

    template.setEnableTransactionSupport(true);
    

    어쩌면 당신은 트랜잭션을 사용하려면이 사용할 수 있습니다

  3. ==============================

    3.표트르는 권리입니다. 당신은 SessionCallback에 넣어해야합니다.

    표트르는 권리입니다. 당신은 SessionCallback에 넣어해야합니다.

    여기에 봄 데이터 레디 스와 거래를하는 빠른 요약 한 것입니다 :

    https://github.com/eric-wu/dashboard/wiki/3.-Redis-Transactions-via-Spring-Data-Redis

    귀하의 경우를 들어, 아래로 스크롤하여 "시계, MULTI 및 EXEC를 사용하여 낙관적 잠금"봐.

  4. from https://stackoverflow.com/questions/11148383/how-to-implement-redis-multi-exec-by-using-spring-data-redis by cc-by-sa and MIT license