Redis Transactions

레디스 트랜잭션은 RedisTemplate의 multi, exec, discard를 통해 제공됩니다. 그러나 RedisTemplate 동일한 연결을 사용하여 트랜잭션의 모든 작업을 실행한다고 보장할 수 없습니다.

Spring Data Redis는 Redis 트랜잭션 SessionCallback을 사용할 때와 같이 동일한 작업으로 여러 작업을 수행해야 할 때 사용할 인터페이스를 제공합니다.

List<Object> txResults = redisTemplate.execute(new SessionCallBack<List<Object>>() {
	public List<Object> execute(RedisOperations operations) throws DataAcessException {
		operations.multi();
		operations.opsForSet().add("key", "value")

		return operations.exec();
	}
})

RedisTemplate 값, 해시 키 를 직렬화를 사용하여 exec 반환하기 전에 모든 결과를 역직렬화 합니다. exec 트랜잭션 결과에 대한 사용자 지정 직렬 변환기를 전달할 수 있는 추가방법이 있습니다.

버전 1.1 부터 exec 메소드의 중요한 변경이 이러어졌습니다.
이전에는 이러한 메소드가 커넥터에서 직접 트랜잰셕 결과를 반환했습니다.
이는 데이터 유형이 메소드에서 반환된 유형과 종종 다르다는 것을 의미합니다.
예를 들어, 요소가 정렬된 집합에 추가되었는지 여부를 나타내는 boolean을 반환합니다.
또 다른 차이점은 대부분의 커넥터와 같은 작업에 대해 상태 응답을 반환한다는 것입니다.
이러한 응답은 일반적으로 Spring Data Redis에서 삭제됩니다.
1.1 이전에는 결과에 대해 이러한 변환이 수행되지 않았습니다.
또한 결과를 역직렬화되지 않았습니다.
그래서 종종 원시 바이트 배열을 포함했습니다. 
이 변경으로 인해 애플리케이션이 중단되는 경우 이 동작을 비활성화 하려면
convertPipelineAndTxResults false를 설정하십시오

@Transactional 지원

기본적으로 RedisTemplate 관리되는 Spring 트랜잭션에 참여되지 않습니다. 원하는 경우에 RedisTemplate 사용할 때 레디스 트랜잭션을 사용하도록 @Transactional 을 쓰거나 TransactionTemplate을 하면 됩니다. 이경우 명시적으로 각 트랜잭션을 지원을 활성화 해야합니다. RedisTemplate .setEnableTransactionSupport(true). 트랜잭션 서포트를 활성화하면 RedisConnection의 현재 트랜잭션에 바인딩(ThreadLocal) 됩니다. Redis 트랜잭션은 배치 지향적입니다. 진행 중인 트랜잭션 중에 실행된 명령은 대기열에 있으며 트랜잭션을 커밋할때만 적용됩니다.

Spring Data Redis는 진행중인 트랜잭션에서 읽기 전용 명려과 쓰기 명령을 구분합니다. 같은 읽기 전용 명령은 읽기를 허용 새로운(스레드 바인딩되지 않은) 명령으로 파이프됩니다. 쓰기명령은 RedisTemplate 커밋시 대기하고 적용됩니다.

@Configuration
@EnableTransactionManagement                                 
public class RedisTxContextConfiguration {

  @Bean
  public StringRedisTemplate redisTemplate() {
    StringRedisTemplate template = new StringRedisTemplate(redisConnectionFactory());
    // explicitly enable transaction support
    template.setEnableTransactionSupport(true);              
    return template;
  }

  @Bean
  public RedisConnectionFactory redisConnectionFactory() {
    // jedis || Lettuce
  }

  @Bean
  public PlatformTransactionManager transactionManager() throws SQLException {
    return new DataSourceTransactionManager(dataSource());   
  }

  @Bean
  public DataSource dataSource() throws SQLException {
    // ...
  }
}