Using Flyway To Manage Database Migration In Spring Boot Microservices Application


Today, I was working on an application that uses Microservices based architecture. Each Microservice had its own schema and they talk to each other using their published contracts.

We wanted to keep database migration script with each Microservice rather than keeping a common module to manage database Migrations. We might later migrate to common module for database migration but we want to start by keeping schema for each Microservice separate.

In Spring Boot services, Flyway is auto-configured with flyway-core dependency is on the classpath.

Flyway uses flyway_schema_history table to track the state of the database. This table is created in the default schema. Once it finds the table it scans the classpath looking for SQL or Java migration scripts. Once found it applies the migration scripts and store state in the flyway_schema_history table as shown below.

installed_rankversiondescriptiontypescriptchecksuminstalled_byinstalled_onexecution_timesuccess
11application schema initSQLV1__application_schema_init.sql311111312sa2020-06-19 12:10:571581

This works great when you have single application/service/module responsible for applying database migration scripts.

When multiple services tries to use the default Spring Boot Flyway configuration then you will get following exception.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.api.FlywayException: Validate failed: 
Migration checksum mismatch for migration version 1

The above exception is because first service applied the database migration and updated the flyway_schema_history table. When second table tries to apply the database migration it finds that both scripts checksum are different although version number is 1.

To fix this error we can specify different table names for each Microservice using the following property.

spring.flyway.table=service1_flyway_schema_history

After making the change once you run both the services you will get following exception.

org.flywaydb.core.api.FlywayException: Found non-empty schema

To solve this exception we will have to set two more properties.

spring.flyway.baseline-on-migrate=true
spring.flyway.baseline-version=0

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s