programing

Spring Boot 애플리케이션에서 Flyway를 사용한 여러 데이터 소스 이행

closeapi 2023. 3. 27. 21:15
반응형

Spring Boot 애플리케이션에서 Flyway를 사용한 여러 데이터 소스 이행

Spring Boot 기반 앱에서 DB 마이그레이션을 위해 Flyway를 사용하고 있으며, 여러 데이터 소스 전략을 사용하면서 멀티 테넌시(Multi Tenancy) 지원을 도입해야 합니다.그 일환으로서 복수의 데이터 소스의 이행도 서포트할 필요가 있습니다.모든 데이터 소스는 동일한 구조를 유지하며 모든 데이터 소스의 마이그레이션에 동일한 마이그레이션 스크립트를 사용해야 합니다.또, 이행은 애플리케이션 기동시에 실시할 필요가 있습니다(다만, 메이븐 플러그인은 복수의 데이터 소스를 이행하도록 설정할 수 있는 것 같습니다.이를 실현하기 위해 사용하는 최선의 접근법은 무엇입니까?앱에 이미 데이터 소스 빈이 정의되어 있지만 Flyway는 기본 데이터 소스에 대해서만 마이그레이션을 실행합니다.

@Roger Thomas가 Spring Boot 방식으로 응답하도록 하려면:

가장 쉬운 해결책은 기본 데이터 소스에 주석을 다는 것입니다.@Primary(이미 이행이 끝난 상태), 부트스트랩이 프라이머리 데이터소스를 '정상적인' 방법으로 이행하도록 하는 것만으로 끝납니다.

그 외의 데이터 소스의 경우는, 이러한 소스를 수동으로 이행합니다.

@Configuration
public class FlywaySlaveInitializer {

     @Autowired private DataSource dataSource2;
     @Autowired private DataSource dataSource3;
     //other datasources

     @PostConstruct
     public void migrateFlyway() {
         Flyway flyway = new Flyway();
         //if default config is not sufficient, call setters here

         //source 2
         flyway.setDataSource(dataSource2);
         flyway.setLocations("db/migration_source_2");
         flyway.migrate();

         //source 3
         flyway.setDataSource(dataSource3);
         flyway.setLocations("db/migration_source_3");
         flyway.migrate();
     }
}

Flyway는 Java 내에서 코드화된 마이그레이션을 지원하므로 애플리케이션 시작 중에 Flyway를 시작할 수 있습니다.

https://flywaydb.org/documentation/migration/java

구성 파일을 통해 다수의 데이터 소스를 대상으로 하는 Flyway를 어떻게 구성할지는 모르겠습니다.자체 개발은 Java를 사용하여 작업해야 하는 데이터 소스당 한 번 Flyway에 전화를 거는 것을 기반으로 합니다.스프링 부트는 다음과 같이 표시된 콩의 자동 배선을 지원합니다.@FlywayDataSource하지만 어떻게 사용할 수 있는지 알아보지 못했습니다.

인자바 솔루션의 경우 코드는 다음과 같이 단순할 수 있습니다.

    Flyway flyway = new Flyway();

    // Set the data source
    flyway.setDataSource(dataSource);

    // Where to search for classes to be executed or SQL scripts to be found
    flyway.setLocations("net.somewhere.flyway");

    flyway.setTarget(MigrationVersion.LATEST);
    flyway.migrate();

같은 문제를 안고 있다니...제가 알아봤는데spring-boot-autoconfigure에서 V 2.2.4의 아티팩트org.springframework.boot.autoconfigure.flyway패키지와 나는 주석을 발견했다.FlywayDataSource.

Flyway에서 사용하고자 하는 데이터 소스에 주석을 달면 효과가 있습니다.
다음과 같은 경우:

@FlywayDataSource
@Bean(name = "someDatasource")
public DataSource someDatasource(...) {
        <build and return your datasource>
}

용이한 솔루션을 찾았습니다.EMF 작성 시 스텝을 추가했습니다.

@Qualifier(EMF2)
@Bean(name = EMF2)
public LocalContainerEntityManagerFactoryBean entityManagerFactory2(
    final EntityManagerFactoryBuilder builder
) {
    final DataSource dataSource = dataSource2();
    Flyway.configure()
          .dataSource(dataSource)
          .locations("db/migration/ds2")
          .load()
          .migrate();
    return builder
        .dataSource(dataSource)
        .packages(Role.class)
        .properties(jpaProperties2().getProperties())
        .persistenceUnit("domain2")
        .build();
}

나는 봄을 무효화했다.flyway. 활성화 되어 있습니다.

SQL 파일은 resources/db/migration/ds1/... 및 resources/db/migration/ds2/...에 있습니다.

이건 나한테 효과가 있었어.

import javax.annotation.PostConstruct;
import org.flywaydb.core.Flyway;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FlywaySlaveInitializer {

  @Value("${firstDatasource.db.url}")
  String firstDatasourceUrl;
  @Value("${firstDatasource.db.user}")
  String firstDatasourceUser;
  @Value("${firstDatasource.db.password}")
  String firstDatasourcePassword;

  @Value("${secondDatasource.db.url}")
  String secondDatasourceUrl;
  @Value("${secondDatasource.db.user}")
  String secondDatasourceUser;
  @Value("${secondDatasource.db.password}")
  String secondDatasourcePassword;


  @PostConstruct
  public void migrateFlyway() {
    Flyway flywayIntegration = Flyway.configure()
        .dataSource(firstDatasourceUrl, firstDatasourceUser, firstDatasourcePassword)
        .locations("filesystem:./src/main/resources/migration.first")
        .load();

    Flyway flywayPhenom = Flyway.configure()
        .dataSource(secondDatasourceUrl, secondDatasourceUser, secondDatasourcePassword)
        .locations("filesystem:./src/main/resources/migration.second")
        .load();

    flywayIntegration.migrate();
    flywayPhenom.migrate();
  }

}

그리고 내 application.yml에서 이 속성은 다음과 같습니다.

spring:
  flyway:
    enabled: false

언급URL : https://stackoverflow.com/questions/37281229/multiple-datasources-migrations-using-flyway-in-a-spring-boot-application

반응형