source

2개의 데이터 소스를 Flyway와 연계하여 스프링 부트에서 HikariCP를 사용하는 방법

itover 2023. 4. 2. 10:22
반응형

2개의 데이터 소스를 Flyway와 연계하여 스프링 부트에서 HikariCP를 사용하는 방법

스프링 부트 어플리케이션에서 HikariCP를 JDBC 접속 풀로 사용하고 싶다.2개의 데이터 소스(MySQL 데이터베이스가 프라이머리 데이터베이스로 Hibernate를 통해 이들 데이터에 액세스하고 추가로 Oracle 데이터베이스로 JDB를 통해 다른 데이터를 읽어낼 수 있음)가 있습니다.CTemplate).

MySQL 데이터 소스를 기본 빈으로 설정합니다.

@Bean
@Primary
@ConfigurationProperties("spring.datasource")
public DataSourceProperties mySQLDataSourceProperties() {
    return new DataSourceProperties();
}


@Bean
@Primary
@ConfigurationProperties("spring.datasource")
public DataSource mySQLDataSource() {
    return mySQLDataSourceProperties().initializeDataSourceBuilder().build();
}

@Bean
@ConfigurationProperties("oracle.datasource")
public DataSourceProperties oracleDataSourceProperties() {
    return new DataSourceProperties();
}

@Bean(name = "oracleDatabase")
@ConfigurationProperties("oracle.datasource")
public DataSource oracleDataSource() {
    return oracleDataSourceProperties().initializeDataSourceBuilder().build();
}

 @Bean
 public JdbcTemplate oracleJdbcTemplate(@Qualifier("oracleDatabase") DataSource oracleDb) {
     return new JdbcTemplate(oracleDb);
 }

다음 설정을 application.properties에 넣습니다.

spring.datasource.type=com.zaxxer.hikari.HikariDataSource

spring.datasource.hikari.minimum-idle=7
spring.datasource.hikari.pool-name=Test-1

spring.datasource.hikari.data-source-properties.prepStmtCacheSize=250
spring.datasource.hikari.data-source-properties.prepStmtCacheSqlLimit=2048
spring.datasource.hikari.data-source-properties.cachePrepStmts=true
spring.datasource.hikari.data-source-properties.useServerPrepStmts=true

유감스럽게도 다음 HikariCP 설정은 읽히지 않습니다.

 HikariConfig - dataSourceJNDI..................none
 HikariConfig - dataSourceProperties............{password=<masked>}
 HikariConfig - driverClassName................."com.mysql.jdbc.Driver"
 HikariConfig - healthCheckProperties...........{}
 HikariConfig - healthCheckRegistry.............none
 HikariConfig - idleTimeout.....................600000
 HikariConfig - initializationFailFast..........true
 HikariConfig - initializationFailTimeout.......1
 HikariConfig - isolateInternalQueries..........false
 HikariConfig - jdbc4ConnectionTest.............false
 HikariConfig - jdbcUrl........................."jdbc:mysql://localhost:3306/testDB"
 HikariConfig - leakDetectionThreshold..........0
 HikariConfig - maxLifetime.....................1800000
 HikariConfig - maximumPoolSize.................10
 HikariConfig - metricRegistry..................none
 HikariConfig - metricsTrackerFactory...........none
 HikariConfig - minimumIdle.....................10
 HikariConfig - password........................<masked>
 HikariConfig - poolName........................"HikariPool-1"

HikariCP 콩을 만들고 DataSource 자동 구성을 비활성화하여 "spring.datasource"를 삭제합니다.

@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
@SpringBootApplication
@ComponentScan
public class SpringApplication {


@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource.hikari")
public HikariConfig hikariConfig() {
    return new HikariConfig();
}

@Bean
public DataSource dataSource() {
    return new HikariDataSource(hikariConfig());
}

문제를 해결합니다.

 HikariConfig - dataSourceJNDI..................none
 HikariConfig - dataSourceProperties............{password=<masked>, prepStmtCacheSqlLimit=2048, cachePrepStmts=true, useServerPrepStmts=true, prepStmtCacheSize=250}
 HikariConfig - driverClassName................."com.mysql.jdbc.Driver"
 HikariConfig - healthCheckProperties...........{}
 HikariConfig - healthCheckRegistry.............none
 HikariConfig - idleTimeout.....................600000
 HikariConfig - initializationFailFast..........true
 HikariConfig - initializationFailTimeout.......1
 HikariConfig - isolateInternalQueries..........false
 HikariConfig - jdbc4ConnectionTest.............false
 HikariConfig - jdbcUrl........................."jdbc:mysql://localhost:3306/testDB?autoReconnect=true"
 HikariConfig - leakDetectionThreshold..........0
 HikariConfig - maxLifetime.....................1800000
 HikariConfig - poolName........................"Test-1"

그러나 Flyway에 이전에 표시되지 않았던 이상한 경고가 표시되므로 Spring 어플리케이션을 실행하기 전에 수동으로 데이터베이스 스키마를 작성해야 합니다.즉, create schema는 더 이상 작동하지 않습니다.

[WARN ] JdbcTemplate - DB: Can't create database 'test'; database exists (SQL State: HY000 - Error Code: 1007)
[WARN ] JdbcTemplate - DB: Unknown table 'testSchema.tenant' (SQL State: 42S02 - Error Code: 1051)
[WARN ] JdbcTemplate - DB: Unknown table 'testSchema.user' (SQL State: 42S02 - Error Code: 1051) 

Flyway SQL 스크립트는 플레인 DDL 스크립트입니다.

CREATE SCHEMA IF NOT EXISTS `testSchema` DEFAULT CHARACTER SET utf8 ;

DROP TABLE IF EXISTS `testSchema`.`tenant`;

CREATE TABLE `testSchema`.`tenant` (
  `id` int NOT NULL AUTO_INCREMENT,

Flyway가 스키마 작성 및 경고 표시를 중지하므로 Auto-Datasource 구성을 비활성화하는 것은 최선의 해결책이 아니라고 생각합니다.이 문제를 해결할 다른 방법이 있나요?

자신의 것을 선언DataSource에서는 데이터 소스의 Spring Boot 자동 설정이 이미 무효가 되어 있습니다.즉, 다음과 같은 효과는 없습니다.

@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})

Hikari 고유의 설정을 MySQL에 바인드하지 않은 것이 문제라고 생각합니다.DataSource다음과 같은 작업을 수행해야 합니다.

@Bean
@Primary
@ConfigurationProperties("spring.datasource.hikari")
public DataSource mySQLDataSource() {
    return mySQLDataSourceProperties().initializeDataSourceBuilder().build();
}

이 말은 즉,mySQLDataSourceProperties는 범용 데이터 소스 설정으로 구성됩니다.그런 다음 다음,HikariDataSource이것은, Hikari 고유의 설정으로 한층 더 설정됩니다.

당신의 빠르고 가치 있는 답변에 감사드려요! 당신은 저를 올바른 길로 인도해 주셨어요.만지작거려 본 결과, 이 설정이 유효하게 되어 있었습니다.

    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource") 
  //@ConfigurationProperties("spring.datasource.hikari") can also be used, no difference
    public DataSourceProperties mySQLDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource.hikari")
    public DataSource mySQLDataSource() {
        return mySQLDataSourceProperties().initializeDataSourceBuilder().build();
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.hikari")
    public HikariConfig hikariConfig() {
        return new HikariConfig();
    }

    @Bean
    public DataSource dataSource() {
        return new HikariDataSource(hikariConfig());
    }

application.properties에 다음 설정을 추가해야 했습니다.

# this is absolutely mandatory otherwise BeanInstantiationException in mySQLDataSource ! 
spring.datasource.url=${JDBC_CONNECTION_STRING}

spring.datasource.hikari.jdbc-url=${JDBC_CONNECTION_STRING}

spring.datasource.hikari.username=user
spring.datasource.hikari.password=pass

나는 다음과 같은 접근방식을 사용했다.

    first.datasource.jdbc-url=jdbc-url
    first.datasource.username=username
    first.datasource.password=password
    .
    .
    .
    .
    =================== In Java Configuration File ==================
    
    @Primary
   @Bean(name = "firstDataSource")
        @ConfigurationProperties(prefix = "first.datasource")
        public DataSource dataSource() {
            return DataSourceBuilder.create().build();
        }
    

@Primary
        @Bean(name = "firstEntityManagerFactory")
        public LocalContainerEntityManagerFactoryBean barEntityManagerFactory(EntityManagerFactoryBuilder builder,
                @Qualifier("firstDataSource") DataSource dataSource) {
            Map<String, String> props = new HashMap<String, String>();
            props.put("spring.jpa.database-platform",  "org.hibernate.dialect.Oracle12cDialect");
    .
    .
    .
    
            return builder.dataSource(dataSource).packages("com.first.entity").persistenceUnit("firstDB")
                    .properties(props)
                    .build();
        }

    @Primary
        @Bean(name = "firstTransactionManager")
        public PlatformTransactionManager firstTransactionManager(
                @Qualifier("firstEntityManagerFactory") EntityManagerFactory firstEntityManagerFactory) {
            return new JpaTransactionManager(firstEntityManagerFactory);
        }

second.datasource.jdbc-url=jdbc-url
second.datasource.username=username
second.datasource.password=password
.
.
.
.
=================== In Java Configuration File ==================

   @Bean(name = "secondDataSource")
    @ConfigurationProperties(prefix = "second.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "secondEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean barEntityManagerFactory(EntityManagerFactoryBuilder builder,
            @Qualifier("secondDataSource") DataSource dataSource) {
        Map<String, String> props = new HashMap<String, String>();
        props.put("spring.jpa.database-platform",  "org.hibernate.dialect.Oracle12cDialect");
.
.
.

        return builder.dataSource(dataSource).packages("com.second.entity").persistenceUnit("secondDB")
                .properties(props)
                .build();
    }

    @Bean(name = "secondTransactionManager")
    public PlatformTransactionManager secondTransactionManager(
            @Qualifier("secondEntityManagerFactory") EntityManagerFactory secondEntityManagerFactory) {
        return new JpaTransactionManager(secondEntityManagerFactory);
    }

언급URL : https://stackoverflow.com/questions/44373186/how-to-use-hikaricp-in-spring-boot-with-two-datasources-in-conjunction-with-flyw

반응형