지연로딩으로 datasource connection 실패
LazyConnectionDataSourceProxy
를 활용하여 @Transactional
readonly 값에 따라서 master 혹은 slave datasource를 선택하도록 (지연로딩) 구현했었다.
그랬더니 배포시에 slave datasource의 커넥션 연결 실패가 발생했다.
실패 발생 이유
스프링의 트랜잭션 동기화는 connection 객체를 보관하고, connection을 종료시키지 않고 호출될때 꺼내야 반환한다.
@DependsOn({"masterDataSource","slaveDataSource"})
@Bean(name = "routingDataSource")
public DataSource routingDataSource(@Qualifier("masterDataSource") DataSource masterDataSource,
@Qualifier("slaveDataSource") DataSource slaveDataSource) {
RoutingDataSource routingDataSource = new RoutingDataSource();
Map<Object, Object> dataSourceMap = new HashMap<>();
dataSourceMap.put(DataSourceType.MASTER, masterDataSource);
dataSourceMap.put(DataSourceType.SLAVE, slaveDataSource);
routingDataSource.setTargetDataSources(dataSourceMap);
routingDataSource.setDefaultTargetDataSource(masterDataSource);
return routingDataSource;
}
어플리케이션이 최초에 배포됐을때는 routingDataSource.setDefaultTargetDataSource(masterDataSource);
라인에 의해서 master datasource는 connection을 확보하고 있었지만, salve datasource는 @Transactional
가 붙은 쿼리가 실행되기 전까지 datasource를 최초에 연결하지 않았음으로 connection이 없다.
실제로 readonly=true 쿼리가 실행되어 slave datasource로 connection이 잡히기 전까지 slave datasource connection을 요구한 호출들은 실패하고 마는 것이다.
해결 방법
내가 참여중이던 프로젝트에서는 CommandLineRunner
를 만들고, 그 안에 readOnly=true인 쿼리를 실행시켜서 배포직후에 slave datasource 연결을 시켜 connection을 보관하도록 한다.
참고 블로그에서 보았던 해결 방법은 프록시 datasource를 만들어서 설정하는 방법이였다.
참고
Author And Source
이 문제에 관하여(지연로딩으로 datasource connection 실패), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@haeyon098/지연로딩으로-datasource-connection-실패저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)