# 9. The contract migration [← 8. The rolling window proof](08-the-rolling-window-proof.md) · [Next: 10. What happens if you drop too soon →](10-what-happens-if-you-drop-too-soon.md) Deploy 4 is split into two parts on purpose, the same way Deploy 1 was schema-only and Deploys 2/3 were code-only: - **4a — code.** A rolling restart to Stage 4, which never reads or writes `email`. The old column is still physically present; Stage 4 code simply ignores it. - **4b — schema.** Once every replica is confirmed on Stage 4 code, and only then, [`V3__drop_email_column.sql`](https://ankurm.com/git.app/asmhatre/spring-boot-demo/src/branch/main/db-migrations-expand-contract/src/main/resources/db/migration/V3__drop_email_column.sql) runs, with zero app restarts: ```sql ALTER TABLE customers DROP COLUMN email; ``` [`ContractSafetyTest`](https://ankurm.com/git.app/asmhatre/spring-boot-demo/src/branch/main/db-migrations-expand-contract/src/test/java/com/ankurm/expandcontract/ContractSafetyTest.java) confirms the happy path: Stage 4 reads and writes keep working, both for a row that existed before the drop and for one created entirely after it — ``` -- Stage 4 read, after V3 dropped the email column -- Customer[id=1, name=Annie Easley, email=annie@example.test] -- Stage 4 create + read, entirely after the drop -- Customer[id=2, name=Mary Allen Wilkes, email=mary@example.test] ``` Full transcript: [`docs/output/09-contract-safety.txt`](https://ankurm.com/git.app/asmhatre/spring-boot-demo/src/branch/main/db-migrations-expand-contract/docs/output/09-contract-safety.txt). Why not drop the column in the same deploy as the code change? Because "every replica is confirmed on Stage 4" is a statement about the *fleet*, and a rolling deploy makes it true only once, at the very end of the rollout — never at the moment the deploy starts. Running 4b before that point is dropping a column a live Stage 1, 2, or 3 replica might still need. What that actually looks like, captured directly, is [chapter 10](10-what-happens-if-you-drop-too-soon.md). ## Going deeper - The DDL Deploy 4b runs is not, on this specific database engine, quite as free of side effects on concurrent traffic as "just a schema change" suggests — see [chapter 14](14-the-ddl-lock-window.md) for what H2 actually does while this statement executes. [← 8. The rolling window proof](08-the-rolling-window-proof.md) · [Next: 10. What happens if you drop too soon →](10-what-happens-if-you-drop-too-soon.md)