Backend/Spring+Boot

readOnly 구분에 따른 커넥션 선택

findmypiece 2021. 12. 15. 00:58
728x90

jdbc:mysql:replication 스키마도 그렇고 아래에서 설명한 다중DB 커넥션 설정도 그렇고 현재 트랜잭션의 readOnly 값에 따라 master, slave DB가 선택된다.

https://findmypiece.tistory.com/255?category=968583

write 작업을 하는 커넥션의 경우 readOnly 값을 기본값인 false 로 지정해서 사용할텐데 대부분 트랜잭션에는 단순히 CUD 쿼리 뿐만 아니라 Read 쿼리도 포함되어 있다.

 

그렇다면 트래픽을 완전하게 분리하기 위해서 readOnly=false 로 지정된 트랜잭션의 쿼리 중 Read 쿼리는 readOnly=true 로 지정해서 slave DB에서 수행되게 해야 할까?

 

Spring에서 제공하는 트랜잭션 전파 규칙을 이용하면 이런 처리가 가능하다. 예를 들어 Service 단에 @Transactional 이 지정되어 있다면 Dao 단의 select 쿼리를 수행하는 메소드에 @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true를 추가로 지정하면 된다.

 

이렇게 되면 readOnly=false 인 트랜잭션에 포함된 작업 중 select 쿼리는 slave DB에서 새로운 커넥션을 얻어서 수행되게 할 수 있다.

 

그런데 이 작업은 하지 않느니만 못하다. 1개의 master 커넥션만으로 처리할 수 있는 작업을 여러개의 커넥션을 이용하게 되기 때문이다. 트래픽이 몰리면 안그래도 커넥션 고갈이 발생할텐데 굳이 이렇게 커넥션을 낭비할 필요는 없다.

 

일반적으로 JPA를 사용하는 Spring 환경이라면 Service 단 클래스에 @Transactional 을 지정하고 순수하게 Read 작업만 포함된 메소드에만 @Transactional(readOnly = true) 를 명시하도록 한다.

 

클래스에 @Transactional 를 지정할 경우 기본적으로 해당 클래스에 포함된 모든 메소드에 트랜잭션이 적용되는데 메소드에 다시 @Transactional(readOnly = true) 와 같이 트랜잭션을 지정할 경우 최종적으로 메소드에 지정된 트랜잭션 설정이 적용된다.

728x90