현재 refresh token을 관리하기 위해서 redis를 사용하였다.
서비스 단계에서 transaction 을 처리하면서, redis에서 트랜젝션의 유무가 궁금해졌고, 이번기회에 찾아보게 되었다.
Redis의 트랜잭션은 어떻게 이용사용할 수 있을까요 ? 트랜잭션을 유지하기 위해서는 순차성을 가져야 하고 도중에 명령어가 치고 들어오지 못하게 Lock이 필요합니다. Redis에서는 MULTI, EXEC, DISCARD 그리고 WATCH 명령어를 이용하면됩니다. 각 명령어에 대한 설명은 아래와 같습니다.
@Transactional을 사용해서 redis Transaction을 유지하기 위해서는 redisTemplate 설정에 setEnableTransactionSupport(true)를 추가해야합니다. @Transactional를 redis와 이용하면 기본적으로 ThreadLocal 기반으로 메서드 시작시 transaction 시작으로 MULTI, 메서드 종료시 transaction 커밋으로 EXEC 명령어를 실행하는 것으로 구현하고 있습니다. 만약 Exception이 발생하면 DISCARD가 실행됩니다.
레디스도 PlatformTransactionManage를 통해서 트랜젝션을 관리할 수 있다. spring-data-redis에서는 이를 제공해주지 않기 때문에, JDBC 또는 JPA 와 같은 다른 transaction manager 를 갖고 있는 의존성을 통해 사용할 수 있다.
이는 이미 등록되어 있기 때문에, AutoConfiguration에 의해서 @EnableTransactionManagement가 사용되어진다. 따라서 따로 등록할 필요가 없다.
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<?, ?> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<byte[], byte[]> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setEnableTransactionSupport(true); // redis Transaction On !
return redisTemplate;
}
@Bean // 만약 PlatformTransactionManager 등록이 안되어 있다면 해야함, 되어있다면 할 필요 없음
public PlatformTransactionManager transactionManager() throws SQLException {
// 사용하고 있는 datasource 관련 내용, 아래는 JDBC
return new DataSourceTransactionManager(datasource());
// JPA 사용하고 있다면 아래처럼 사용하고 있음
return new JpaTransactionManager(entityManagerFactory);
}
}