지연로딩으로 datasource connection 실패

h블로그·2022년 4월 4일
0

multidatasource

목록 보기
2/2

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를 만들어서 설정하는 방법이였다.

참고

https://chagokx2.tistory.com/103

profile
😎🙈🙈🙈🤓

0개의 댓글