Spring에 있는 AbstractRoutingDataSource 는
여러개의 데이터 소스를 하나로 묶고 자동으로 분기 처리를 해주는 Spring 기본 클래스
이번 프로젝트에서 ReplicationRoutingDataSource
클래스에서 상속받아 구현했는데,
이 클래스만으로 설정을 끝내면 TransactionSynchronizationManager
가 @Transactional
로 선언된 현재 스레드의 트랜잭션 상태를 읽어오는게 가능하더라도 동기화(synchronation)시점과 Connection 객체를 가져오는 시점에 문제가 있기 때문에 다른 설정도 추가했습니다.
Spring은 @Transactional을 만나면 다음 순서로 일을 처리합니다.
TransactionManager 선별 → DataSource에서 Connection 획득 → Transaction 동기화(Synchronization)
트랜잭션 동기화를 마친 뒤에 ReplicationRoutingDataSourc.java
에서 커넥션을 획득해야만 이게 올바로 동작하는데 그 순서가 뒤바뀌어 있기 때문에 동기화와 connection 객체를 가져오는 시점에 문제가 발생합니다.
이 문제는 ReplicationRoutingDataSource.java
를 LazyConnectionDataSoruceProxy
로 감싸주는 것으로 해결할 수 있습니다.
LazyConnectionDataSoruceProxy
는 실질적인 쿼리 실행 여부와 상관없이 트랜잭션이 걸리면 무조건 Connection 객체를 확보하는 Spring의 단점을 보완하여 트랜잭션 시작 시에 Connection Proxy 객체를 리턴하고 실제로 쿼리가 발생할 때 데이터 소스에서 getConnection()을 호출하는 역할을 하는 것이라고 합니다.
모든 설정을 완료하면, 다음과 같은 작동 순서로 처리됩니다.
TransactionManager 선별