使用Maven执行Liquibase回滚时遇RollbackImpossibleException错误求助
解决Liquibase回滚RawSQLChange报错的问题
你碰到的这个RollbackImpossibleException其实很好理解:Liquibase没法自动推断**原生SQL变更(RawSQLChange)**的逆操作——毕竟你写的是自定义SQL,它完全不知道该怎么回滚这些操作。下面给你两种实用的解决思路:
思路1:给每个原生SQL变更集手动添加回滚语句
这是最直接的方案,针对每个创建schema、表的SQL,明确写出对应的回滚逻辑。比如你的变更日志可以改成这样:
<changeSet id="create-myschema" author="your-name"> <sql>CREATE SCHEMA myschema;</sql> <rollback>DROP SCHEMA myschema CASCADE;</rollback> <!-- 手动指定回滚SQL --> </changeSet> <changeSet id="create-table1" author="your-name"> <sql>CREATE TABLE myschema.table1 (id INT PRIMARY KEY, name VARCHAR(50));</sql> <rollback>DROP TABLE myschema.table1;</rollback> </changeSet> <changeSet id="create-table2" author="your-name"> <sql>CREATE TABLE myschema.table2 (id INT PRIMARY KEY, table1_id INT REFERENCES myschema.table1(id));</sql> <rollback>DROP TABLE myschema.table2;</rollback> </changeSet> <changeSet id="tag-1.0" author="your-name"> <tagDatabase tag="1.0"/> </changeSet>
修改完成后再执行回滚命令mvn liquibase:rollback -Dliquibase.rollbackTag=1.0,Liquibase就会按顺序执行每个变更集对应的回滚语句了。
思路2:用Liquibase内置结构化变更替代原生SQL
如果你不想手动写回滚语句,可以改用Liquibase提供的内置变更类型(比如createSchema、createTable),这些类型Liquibase会自动生成对应的回滚逻辑。举个例子:
<changeSet id="create-myschema" author="your-name"> <createSchema schemaName="myschema"/> <!-- 无需手动写rollback,Liquibase会自动处理为DROP SCHEMA --> </changeSet> <changeSet id="create-table1" author="your-name"> <createTable tableName="table1" schemaName="myschema"> <column name="id" type="INT"> <constraints primaryKey="true"/> </column> <column name="name" type="VARCHAR(50)"/> </createTable> <!-- 自动回滚逻辑为DROP TABLE --> </changeSet> <changeSet id="create-table2" author="your-name"> <createTable tableName="table2" schemaName="myschema"> <column name="id" type="INT"> <constraints primaryKey="true"/> </column> <column name="table1_id" type="INT"> <constraints referencedTableName="table1" referencedSchemaName="myschema" nullable="false"/> </column> </createTable> </changeSet> <changeSet id="tag-1.0" author="your-name"> <tagDatabase tag="1.0"/> </changeSet>
这种方式不仅省掉了写回滚语句的麻烦,还能降低依赖顺序出错的概率——比如回滚时会自动先删依赖表(table2)再删被依赖表(table1)。
小提示
如果你已经执行过原来的变更集,现在修改日志添加回滚语句不会影响已执行变更的状态,直接重新执行回滚命令就行。
内容的提问来源于stack exchange,提问作者user1491636
相关产品推荐
相关产品推荐

