spring-data-redis의 LettuceConnectionFactory에 setEnableTransactionSupport(boolean) 메서드가 있다.

 

기본값은 false인데, true로 설정하면 트랜잭션을 사용할 수 있게 된다. 그런데 이는 트랜잭션을 지원한다는 의미이지, JDBC처럼 트랜잭션 처리를 알아서 해준다는 의미가 아니다. 

 

레디스에서 트랜잭션을 처리는 MULTI-EXEC 를 사용하여 이루어지는데, 당연하게도 한 트랜잭션은 하나의 커넥션이 MULTI 에서 EXEC 까지 모두 수행해야 한다. setEnableTransactionSupport 는 그것을 돕는다.

 

이 값이 false 이면, MULTI-SET-EXEC 를 호출하면 다음과 같이 동작한다:

getConnection: 커넥션A 획득

MULTI

close

getConnection: 커넥션 B 획득

SET

close

getConnection: 커넥션 C 획득

EXEC

close

 

MULTI 를 포함하여 모든 오퍼레이션이 다른 커넥션에서 호출된다. 마지막 EXEC 에서는 'EXEC without MULTI' 에러가 떨어진다. MULTI 없이 EXEC를 호출했다는 의미이다. 다른 커넥션에서 호출했었으니 하나의 트랜잭션으로 이어지지 않는다.

 

setEnableTransactionSupport 이 true 이면 위 오퍼레이션은 다음과 같이 동작한다:

getConnection: 커넥션A 획득

MULTI

getConnection: 커넥션A 획득

SET

getConnection: 커넥션A 획득

EXEC

 

이와 같이 MULTI에서부터 EXEC 까지의 오퍼레이션을 한 커넥션에 묶어준다. 위 동작의 배경은 LettuceConnection을 가지고 있는 RedisConnectionHolder를 생성하여 스프링의 TransactionSynchronizationManager에 리소스로 바인딩하는 방식을 취한다. JDBC 트랜잭션 관리와 마찬가지로 쓰레드에 자신이 사용할 커넥션을 묶어두는 것이다.

'Redis' 카테고리의 다른 글

Spring-Lettuce 커넥션 풀링 시 shareNativeConnection  (3) 2020.09.02
Lettuce 센티넬 failover 테스트  (0) 2020.09.01

spring-data-redis, Lettuce 사용 시, non-blocking, non-transactional 오퍼레이션은 커넥션 풀을 설정해도 하나의 포트로만 통신한다.

 

이 동작은 LettuceConnectionFactory 의 shareNativeConnection 값에 따라 달라진다. 이 값은 네이티브 커넥션을 공유해서 사용할지 여부를 가리킨다. 기본값이 true 이기에 non-blocking, non-transactional 오퍼레이션은 하나의 커넥션으로만 통신한다. MULTI 를 통해 트랜잭션을 시작하면 새로운 dedicated 커넥션이 할당되어 이것으로 통신한다.

 

언뜻 보기에 이 값을 false로 두고 커넥션 풀을 사용하여 오퍼레이션에 사용되는 커넥션을 분산하면 레디스 처리량이 올라가 성능이 좋아질 것 같지만, 레디스 자체가 싱글 쓰레드로 작동하기 때문에 실제로는 그렇지 않다고 한다. 스프링 부트 github에 부트 레벨에서 이 값을 false 로 설정할 수 있도록 해달라는 issue가 있었는데, 이와 같은 이유로 거부되었다:

 

github.com/spring-projects/spring-boot/issues/14196

 

Allow the ability to set shareNativeConnection to false for LettuceConnectionFactory · Issue #14196 · spring-projects/spring-b

By default, the LettuceConnection will use the sharedConnection for almost all non-tx or non-blocking operations. I have found the exclusive use of the shared connection to not allow very high thro...

github.com

 

이런 이유로, 스탠드얼론 레디스를 사용할 때 트랜잭션을 사용하지 않는다면 커넥션 풀을 사용할 이유가 없다.

 

 

출처:

docs.spring.io/spring-data/data-redis/docs/current/reference/html/#reference

'Redis' 카테고리의 다른 글

Spring-Lettuce setEnableTransactionSupport  (0) 2020.09.02
Lettuce 센티넬 failover 테스트  (0) 2020.09.01

+ Recent posts