Master/Slave (Write/Read) replication connection pool 구현 방법.
Spring 프레임워크를 사용할 경우에는 AbstractRoutingDataSource와 LazyConnectionDataSourceProxy를 조합하면 @Transactional(readOnly=true|false)
로 Master/Slave 커넥션을 선언적으로 조정 가능하다.
이 방식은 Spring Framework의 Transaction과 함께 사용할 때만 작동한다.
최종적으로 LazyConnectionDataSourceProxy
로 감싸야 하는 이유는 Spring이 Transaction을 시작할 때 트랜잭션 정보를 TransactionSynchronizationManager와 동기화 하기 전에 먼저 데이터소스에서 커넥션을 맺어버리기 때문이다.
LazyConnectionDataSourceProxy
를 사용하면 동기화를 마친 뒤에 커넥션을 맺도록 실제 커넥션 맺는 시점을 늦출 수 있다.
import org.springframework.transaction.support.TransactionSynchronizationManager; public class ReplicationRoutingDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return TransactionSynchronizationManager.isCurrentTransactionReadOnly() ? "slave" : "master"; } } // 실제로 Master DB에 접속하는 커넥션 풀 DataSource masterDataSource = ...; // 실제로 Slave DB에 접속하는 커넥션 풀 DataSource slaveDataSource = ...; // @Bean으로 생성 ReplicationRoutingDataSource rrds = new ReplicationRoutingDataSource(); Map<Object, Object> targetDataSources = new HashMap<Object,Object>(); targetDataSources.put("master", masterDataSource); targetDataSources.put("slave", slaveDataSource); rrds.setTargetDataSources(targetDataSources); rrds.setDefaultTargetDataSource(masterDataSource); // 최종적으로 Spring이 사용할 DataSource는 LazyConnectionDataSourceProxy 로 감싸야한다. DataSource dataSource = new LazyConnectionDataSourceProxy(rrds);