Can Grails database-migration rollback safely reverse schema changes across multiple datasources when DDL is non-transactional?
0 reputation · 22 Oct 2021, 05:59 UTC
0 reputation · 22 Oct 2021, 05:59 UTC
In a Grails application that uses the database-migration plugin, schema evolution is tracked through ordered Liquibase changesets. The plugin supports explicit rollback blocks, but rollback safety depends on whether the underlying database treats DDL as transactional. Many storage engines auto-commit DDL, so a failed rollback can leave the schema in an intermediate state.
GORM runtime transactions such as withNewTransaction or TransactionService wrap DML only. Schema modifications made by Hibernate's hbm2ddl.auto at startup occur outside these transaction boundaries. Grails also permits both automatic schema updates and migration-based rollback without enforcing a single source of truth.
In multi-datasource configurations, migrations and rollbacks must be coordinated across every datasource to avoid partial states. The unresolved issue is identifying the reliable rollback boundary when these mechanisms intersect.
hbm2ddl.auto has already modified a schema outside the changelog before a rollback is attempted?No. The Grails database-migration plugin does not treat multiple datasources as one atomic rollback unit. Liquibase tracks changes in a separate DATABASECHANGELOG table for each datasource, and rollback executes independently per datasource. If the second datasource fails, the first is not automatically undone. The only reliable boundary is a single changeset on a single datasource, and only when that engine supports transactional DDL.
If hbm2ddl.auto or the Grails dbCreate setting has modified the schema outside the changelog, rollback cannot see or reverse that drift. The plugin compares changelog history, not the live schema, so it may fail on missing objects or appear to succeed while leaving the database inconsistent with the recorded changesets.
dbCreate: none and ensuring hbm2ddl.auto is not set to update or create in any environment where migrations run.Assuming a recent Grails line with the database-migration plugin, use the plugin's status task (for example, dbm-status) to confirm pending changesets for each datasource, and preview generated SQL with the rollback SQL task (for example, dbm-rollback-sql) before executing anything. Exact task names and flags are version-sensitive, so confirm them against your plugin version.
Provide the database engine and version for each datasource, specifically whether it supports transactional DDL. If an engine supports transactional DDL, per-datasource rollback can be atomic for that datasource alone. If not, even single-datasource rollback is only as safe as the last verified backup, and cross-datasource coordination must rely entirely on the sequential checkpoints above.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.