Spring Boot + Flyway에서 여러 Datasource에 각각 다른 migration 실행

하고 싶은 일


  • Spring Boot 응용 프로그램에서 여러 DataSource 만들기
  • Flyway에서 마이그레이션
  • 여러 DataSource에 대해 별도의 마이그레이션을 수행합니다.

    환경


  • OpenJDK 11
  • Spring Boot 2.4.3
  • Flyway 7.1.1
  • (Kotlin 1.4.30)

  • 포인트


  • Spring에 복수의 DataSource를 작성한다.
  • 그 중 하나를 @Primary로 설정하면 여기로의 마이그레이션이 자동으로 수행됩니다.
  • 그 외의 DataSource 에의 마이그레이션은 수동으로 설정해 준다

  • 설정 방법



    전제



    데이터베이스는 2개 작성 완료. 각각 "origin"과 "dest"라고 부른다.

    datasource 설정



    application.yml에서 여러 데이터 소스 설정



    application.yml에서 다음과 같이 origin과 dest의 여러 데이터 소스를 설정합니다.

    application.yml
    spring:
      datasource:
        origin:
          url: jdbc:mysql://127.0.0.1:3316/main_db
          username: scott
          password: tiger
        dest:
          url: jdbc:mysql://127.0.0.1:3317/main_db
          username: scott
          password: tiger
    

    Spring boot 측의 DataSource 설정



    적당한 장소에 Origin과 Dest의 DataSource의 Bean을 각각 정의해 줍니다.
    요점은 둘 중 하나 (이 경우 Origin)를 @Primary로 설정하는 것입니다.
    이 작업을 수행하면 Primary 측의 Datasource로 마이그레이션할 때 특별한 구성에 필요 없이 작동합니다.
    
    @Component
    @ConfigurationProperties(prefix = "spring.datasource.origin")
    class OriginConfiguration {
        lateinit var url: String
        lateinit var username: String
        lateinit var password: String
    
        @Bean(name = ["origin"])
        @Primary // <= これ大事
        fun dateSource(): DataSource =
            DataSourceBuilder
                .create()
                .url(url)
                .username(username)
                .password(password)
                .build()
    }
    
    @Component
    @ConfigurationProperties(prefix = "spring.datasource.dest")
    class DestConfiguration {
        lateinit var url: String
        lateinit var username: String
        lateinit var password: String
    
        @Bean(name = ["dest"])
        fun dateSource(): DataSource =
            DataSourceBuilder
                .create()
                .url(url)
                .username(username)
                .password(password)
                .build()
    }
    

    Flyway 설정



    migration 파일의 위치



    다음과 같이 db.migration을 dist와 origin으로 나눕니다.


    Origin (Primary) 측의 migration 설정



    위에서 언급했듯이 여기에서는 구성 클래스를 만들 필요는 없지만 migration 파일의 위치 만 application.yml에서 명시해야합니다.
    기본적으로 db/migration이므로 이것을 db/migration/origin으로 변경합니다.

    application.yml
    spring:
      datasource:
        origin:
          url: jdbc:mysql://127.0.0.1:3316/main_db
          username: scott
          password: tiger
        dest:
          url: jdbc:mysql://127.0.0.1:3317/main_db
          username: scott
          password: tiger
      flyway:
        locations: "classpath:db/migration/origin" # <= 追記
    

    Dest 측의 migration 설정



    마지막으로 Dest에 대한 migration 구성 클래스를 만듭니다.
    
    @Configuration
    class FlywayMigrationConfiguration(
        @Qualifier("dest")
        private val destDataSource: DataSource
    ) {
        @PostConstruct
        fun migrateFlyWay() {
            Flyway
                .configure()
                .dataSource(destDataSource)
                .locations("db.migration.dest")
                .target(MigrationVersion.LATEST)
                .load()
                .migrate()
        }
    }
    

    실행



    위의 상태에서 응용 프로그램을 시작하면 의도대로 dest와 origin에 각각 migration이 실행됩니다.

    좋은 웹페이지 즐겨찾기