일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 초대장
- auto configure
- SQL
- oracle
- 티스토리
- smart cast
- dynamic query
- 문법 정리
- resilience4j
- c#
- 알고리즘
- spring
- 오라클
- 유사코드
- JVM
- gradle
- 파이썬 소스
- 파이썬
- 자바
- 운영체제
- 자바 프로젝트
- 학점
- hyperledger
- MongoDB
- 프로젝트
- 백준 알고리즘
- jsp
- 리눅스
- 오라클 디비
- K6
- Today
- Total
모종닷컴
spring boot r2dbc + flyway 본문
spring boot r2dbc와 flyway를 같이 사용하니 flyway가 실행되지 않았던 문제가 있었습니다. 이에 대한 해결법과 원인에 대해 간단하게 공유드립니다.
r2dbc
반응형 프로그래밍을 통해 관계형 데이터베이스와 비동기적으로 통신하기 위한 스펙입니다. spring-boot-r2dbc는 이러한 r2dbc 스펙을 기반으로 만들어진 spring boot 프레임워크 모듈입니다.
flyway
Git이 코드 버전 관리 시스템이라면 flyway는 데이터베이스의 버전 관리 툴 정도로 보시면 될 것 같습니다. 좀 더 풀어서 설명하면 개발자가 애플리케이션에 변경과 관련된 SQL 스크립트를 만들어 배포하면 애플리케이션이 실행될 때 Flyway가 타깃 데이터베이스에 이 SQL을 대신 실행시킵니다. 이렇게 함으로써 애플리케이션과 데이터베이스 호환을 신뢰할 수 있습니다.
예를 들어 엔티티 클래스가 있고 이 엔티티 클래스에 A라는 필드를 추가했다고 가정합니다. 그렇다면 이와 대응되는 sql(= 테이블에 필드 추가하는 쿼리)이 데이터베이스에 적용되어 있어야 애플리케이션이 정상적으로 동작할 텐데요. 이 SQL 스크립트를 애플리케이션에 작성해서 넣어두면 애플리케이션이 실행될 때 Flyway가 데이터베이스에 이 SQL 스크립트를 실행시킬 테니 애플리케이션 <-> 데이터베이스의 호환이 딱 맞아떨어지는 거죠.
spring-boot-r2dbc & flyway를 같이 사용하기
이 두 가지를 함께 사용할 때 주의해야 할 부분이 있습니다. 먼저 spring-boot에는 자동 설정을 위해 spring-boot-autoconfigure라는 모듈이 존재합니다. 그리고 이 프로젝트 중에는 FlywayAutoConfiguration이라는 코드가 존재합니다. 이는 스프링 부트가 실행될 때 Flyway에 대한 설정을 자동으로 하기 위한 코드입니다. 저희가 .properties 파일 혹은 .yml 파일에 몇 가지 프로퍼티만 설정해 주면 되는 이유도 이러한 auto configure 클래스가 있기 때문입니다.
다시 FlywayAutoConfiguration 코드를 보면 몇 가지 조건이 주어집니다. 여기서 @Conditional 어노테이션을 보면 FlywayDataSourceCondition이라는 게 보이는데 이는 스프링 부트에서 Flyway와 관련된 설정을 조건부로 활성화하기 위한 조건 클래스입니다.
FlywayDataSourceCondition 클래스를 보면 다시 조건과 관련된 어노테이션을 볼 수 있는데 DataSource 빈이 있어야 하고, spring.flyway.url이라는 프로퍼티가 설정되어 있어야 한다고 돼있습니다.
문제는 여기서 발생합니다. spring-boot-r2dbc는 DataSource를 빈으로 등록하지 않습니다. DataSource는 전통적인 JDBC와 관련된 인터페이스로 블록킹 스펙이기 때문에, spring-boot-r2dbc에서는 DatabaseClient라는 논블럭킹 IO 인터페이스를 사용합니다.
이러한 이유로 spring-boot-r2dbc와 flyway를 같이 사용할 때 flyway auto configure가 동작하지 않습니다. 따라서 개발자가 수동으로 flyway를 설정 및 마이그레이션을 호출해주어야 합니다.
수동으로 Flyway 실행시켜 주기
방법은 간단합니다. 아래와 같이 Configuration 클래스를 등록해 주시면 됩니다.
@Configuration
@EnableConfigurationProperties(FlywayProperties::class)
class FlywayConfig {
@Bean(initMethod = "migrate")
fun flyway(flywayProperties: FlywayProperties): Flyway {
return Flyway.configure()
.dataSource(flywayProperties.url, flywayProperties.user, flywayProperties.password)
.locations(*flywayProperties.locations.toTypedArray())
.table(flywayProperties.table)
.baselineOnMigrate(true)
.outOfOrder(true)
.load()
}
}
프로퍼티에는 아래와 같이 구성했습니다. 필요 없는 프로퍼티나 추가적인 프로퍼티가 있다면 따로 설정해야 합니다.
spring:
flyway:
url: jdbc:mysql://127.0.0.1:3306/test
user: tester
password: password
locations: classpath:db/migration/all, classpath:db/migration/local
table: flyway_schema
또 주의할만한 부분은 flyway.url에 jdbc 드라이버를 사용하고 있습니다. flyway에 issue가 19년도쯤부터 떠있는데 아지까지는 별다른 지원이 없는 것 같습니다.
댓글 중에 한 유저가 r2dbc-migrate라는 프로젝트를 하나 만들어서 23년 때까지 계속 커밋이 있는 걸 확인은 해봤지만 저는 사용은 아직 안 해봤습니다.
'Programming > Spring' 카테고리의 다른 글
mysql Insert lock wait timeout 조정해보기 with Spring (1) | 2023.04.23 |
---|---|
Mapper 성능 비교 (0) | 2023.02.26 |
Spring Shell을 이용해 나만의 CLI를 만들어보자 (0) | 2023.01.23 |
Spring에서 Redis에 동적데이터 저장하기 (2) | 2023.01.14 |
SQS 메시지 Polling 컨트롤하기. (0) | 2022.12.04 |