Files
spring-boot-demo/db-migrations-flyway-liquibase/docs/01-the-problem-and-mental-model.md
T
asmhatreandClaude Sonnet 5 67e1b2d8a9 db-migrations-flyway-liquibase: fix dead Redgate/Liquibase doc links and back the lock-defaults claim with a real transcript
Several documentation.red-gate.com and liquibase.com URLs added in the previous commit had
since moved (Redgate restructured its docs under /flyway/reference/, Liquibase Pro pricing
moved to /pricing); this repoints them at the current, verified-200 pages. Also captures
docs/output/16-liquibase-lock-defaults-javap.txt, the trimmed javap output backing chapter
11's claim about Liquibase's default lock-poll and lock-wait settings, which chapter 11
previously asserted without a committed artifact to back it.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Q6XdRjtsp4862EM44T7i9a
2026-09-15 07:31:49 +00:00

5.5 KiB

1. The problem, and the smallest correct mental model

Index · Next: 2. Anatomy of a Flyway migration run →

Every app with a database eventually needs a second table added, or a column renamed, or a default changed — and it needs that to happen the same way on the laptop where it was written, on the CI database that only exists for four minutes, and on production, which nobody wants to SSH into and run SQL by hand against. A migration tool's whole job is to make "the same way" true without a human re-typing SQL in three places.

Both tools this module compares solve that with the same core idea: number or name every schema change, keep a table inside the database itself that records which ones have already run, and on startup, apply whatever is missing. That tracking table is the single most important thing to understand before either tool's specific behaviour makes sense — it is the reason a second mvn spring-boot:run doesn't re-run migration 1, and it is the reason two things you're about to read about (checksum validation, and locking) exist at all.

migration files V1__..., V2__... the tool at startup diff files vs. history your database applies what's new tracking table, in that database flyway_schema_history / DATABASECHANGELOG read back on the NEXT startup — this is what "already applied" means

The tracking table is not a cache or a convenience — it is the source of truth the tool consults before touching your schema at all, and it lives in the same database the schema lives in, so it survives redeploys, restarts, and different machines running the same migration set. Flyway's is called flyway_schema_history; Liquibase's is called DATABASECHANGELOG, with a second table, DATABASECHANGELOGLOCK, purely for coordinating concurrent runs (chapters 8 and 11).

What this module actually runs

Everything in this article is one small Spring Boot 4.1.1 module, db-migrations-flyway-liquibase, with both starters on the classpath: spring-boot-starter-flyway and spring-boot-starter-liquibase. Two tiny migration sets live side by side — Flyway's under src/main/resources/db/migration, Liquibase's as one YAML changelog at db.changelog-master.yaml — and every scenario in the chapters that follow is a real JUnit test using Spring's ApplicationContextRunner, which boots a real ApplicationContext against a real H2 file database in milliseconds, with no web server needed. A small Transcript helper writes what each test asserts to a plain text file under docs/output/ — every table and error message quoted in this documentation, and in the published article, was copied out of one of those committed files, not retyped from memory.

The one part of the module that is a running app rather than a test is DbMigrationsApplication, whose only purpose is to expose /diag/migrations (chapter 15) so you can watch a real startup's bookkeeping instead of only reading about it.

Going deeper