Liquibase 4.29编程式更新及回滚支持方案咨询(Spring应用)
Liquibase 4.29编程式执行迁移方案(对齐CLI回滚效果)
一、回滚无效的核心原因
你的问题本质是Spring自动执行与CLI的Liquibase配置不一致,导致变更集记录不匹配:
- Changelog文件路径、上下文(Contexts)、标签(Labels)参数不统一
- Spring数据源与CLI使用的数据库连接参数不同,操作了不同的
databasechangelog表
二、替代弃用update()的推荐编程式方案
使用Liquibase官方推荐的CommandScope执行迁移(CLI底层也用此逻辑),确保与CLI行为完全一致,同时在Spring启动前执行,失败则终止应用:
代码示例
import liquibase.command.CommandScope; import liquibase.command.core.UpdateCommandStep; import liquibase.database.Database; import liquibase.database.DatabaseFactory; import liquibase.database.jvm.JdbcConnection; import liquibase.resource.ClassLoaderResourceAccessor; import org.springframework.boot.context.event.ApplicationStartingEvent; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; import javax.sql.DataSource; import java.sql.Connection; @Component public class LiquibaseMigrationStarter implements ApplicationListener<ApplicationStartingEvent> { private final DataSource dataSource; public LiquibaseMigrationStarter(DataSource dataSource) { this.dataSource = dataSource; } @Override public void onApplicationEvent(ApplicationStartingEvent event) { try (Connection conn = dataSource.getConnection()) { // 初始化数据库连接与资源访问器 Database database = DatabaseFactory.getInstance() .findCorrectDatabaseImplementation(new JdbcConnection(conn)); ClassLoaderResourceAccessor resourceAccessor = new ClassLoaderResourceAccessor(); // 构建Update命令,与CLI参数完全对齐 CommandScope updateCmd = new CommandScope(UpdateCommandStep.COMMAND_NAME) .addArgumentValue(UpdateCommandStep.CHANGELOG_FILE_ARG, "classpath:db/changelog/db.changelog-master.xml") .addArgumentValue(UpdateCommandStep.CONTEXTS_ARG, "") // 与CLI保持一致,比如CLI用--contexts=dev则填"dev" .addArgumentValue(UpdateCommandStep.LABELS_ARG, "") // 与CLI保持一致,比如CLI用--labels=v1则填"v1" .addArgumentValue(UpdateCommandStep.DATABASE_ARG, database) .addArgumentValue(UpdateCommandStep.RESOURCE_ACCESSOR_ARG, resourceAccessor); // 执行迁移,失败直接终止应用 updateCmd.execute(); } catch (Exception e) { System.err.println("Liquibase迁移失败,应用终止:" + e.getMessage()); System.exit(1); } } }
方案说明
- 利用
ApplicationStartingEvent确保迁移在Spring应用核心组件初始化前执行 - 使用
CommandScope完全对齐CLI的执行逻辑,保证变更集记录与CLI执行的一致 - 捕获所有异常并调用
System.exit(1),实现迁移失败则终止应用的要求
三、确保回滚与CLI一致的关键配置
- 统一Changelog路径:
- Spring中用
classpath:前缀(如classpath:db/changelog/db.changelog-master.xml) - CLI中对应使用相对路径(如
src/main/resources/db/changelog/db.changelog-master.xml),或通过--classpath指定资源根目录
- Spring中用
- 匹配上下文与标签:
- 编程式执行时的
CONTEXTS_ARG和LABELS_ARG必须与CLI执行update时的--contexts、--labels参数完全一致
- 编程式执行时的
- 统一数据库连接:
- Spring数据源的URL、用户名、密码需与CLI的
liquibase.properties配置完全相同,确保操作同一份databasechangelog表
- Spring数据源的URL、用户名、密码需与CLI的
四、编程式回滚示例(可选)
如果需要在代码中执行回滚,同样使用CommandScope保证与CLI效果一致:
import liquibase.command.CommandScope; import liquibase.command.core.RollbackCommandStep; import liquibase.database.Database; import liquibase.database.DatabaseFactory; import liquibase.database.jvm.JdbcConnection; import liquibase.resource.ClassLoaderResourceAccessor; import javax.sql.DataSource; import java.sql.Connection; public class LiquibaseRollbackService { private final DataSource dataSource; public LiquibaseRollbackService(DataSource dataSource) { this.dataSource = dataSource; } public void rollbackByCount(String count) throws Exception { try (Connection conn = dataSource.getConnection()) { Database database = DatabaseFactory.getInstance() .findCorrectDatabaseImplementation(new JdbcConnection(conn)); ClassLoaderResourceAccessor resourceAccessor = new ClassLoaderResourceAccessor(); CommandScope rollbackCmd = new CommandScope(RollbackCommandStep.COMMAND_NAME) .addArgumentValue(RollbackCommandStep.CHANGELOG_FILE_ARG, "classpath:db/changelog/db.changelog-master.xml") .addArgumentValue(RollbackCommandStep.ROLLBACK_COUNT_ARG, count) .addArgumentValue(RollbackCommandStep.CONTEXTS_ARG, "") .addArgumentValue(RollbackCommandStep.LABELS_ARG, "") .addArgumentValue(RollbackCommandStep.DATABASE_ARG, database) .addArgumentValue(RollbackCommandStep.RESOURCE_ACCESSOR_ARG, resourceAccessor); rollbackCmd.execute(); } } }
内容的提问来源于stack exchange,提问作者Maddy
相关产品推荐
相关产品推荐

