2

我在具有 Spring 环境的项目中使用 Liquibase。但是回滚功能似乎不起作用。

我怀疑使用 Spring 运行 Liquibase 时不支持回滚功能,因为手册说:

LiquiBase 允许您自动或通过自定义回滚 SQL 撤消对数据库所做的更改。回滚支持在命令行、Ant、Maven 和 Grails 中可用。

但是,很难相信在此设置中不可能进行回滚。所以问题是:“为什么回滚不起作用,我怎样才能让回滚起作用?”


编辑:

我现在意识到我应该问这个问题有点不同。我想要的回滚是在迁移时出现问题时发生的回滚。

我尝试使用事务(因为我假设这些事务在那里),但这并没有达到想要的效果。

将出错的更改集示例:

<changeSet runInTransaction="true">
    <createTable tableName="table1">
        <column name="a" type="int"/>
    </createTable>
    <createTable tableName="table1">
        <column name="a" type="int"/>
    </createTable>
    <createTable tableName="table2">
        <column name="a" type="int"/>
    </createTable>
</changeSet>

当我运行示例更改集时,Liquibase 设法创建 table1 但是当它尝试创建另一个具有相同名称的表时它失败了(显然)。创建的表不会被删除,而是持久化到数据库中。

查看Liquibase 手册,我注意到:

runInTransaction

changeSet 是否应该作为单个事务运行(如果可能)?默认为真。警告:小心这个属性。如果设置为 false 并且在运行包含多个语句的 changeSet 的过程中发生错误,则 LiquiBase databasechangelog 表将处于无效状态 自 1.9

我正在使用 MySQL,但更改集也必须与 MSSQL 和 Oracle 一起使用。

我也在使用 Spring 的事务,并且这些工作完美,关于如何同时获得 Liquibase 的令人敬畏和那些令人敬畏的(数据库独立)事务的任何想法?

4

2 回答 2

1

根据文档,spring 集成似乎旨在支持数据库迁移。

要执行回滚,您可以按如下方式使用 liquibase jar(请参阅命令行文档):

java -jar liquibase.jar \
      --driver=oracle.jdbc.OracleDriver \
      --classpath=website.war \
      --changeLogFile=com/example/db.changelog.xml \
      --url=jdbc:oracle:thin:@localhost:1521:oracle \
      --username=scott \
      --password=tiger \
      rollbackCount ?

数据库 JDBC jar 和更改日志都应该可以从 WAR 文件中获得。

于 2012-12-04T22:21:07.560 回答
1

据我回忆,spring 集成是将数据库迁移为后处理步骤。由于没有交互式步骤,您将没有机会指定命令,例如“回滚一个变更集”。

对于回滚 n 更改等交互式步骤,您需要使用 CLI,或者通过 Ant 或 Maven 构建脚本。

后编辑

事务级回滚取决于底层数据库实现。有些,如 Oracle,不允许在事务回滚期间回滚 DDL 命令(例如 create table)。我发现对于这些情况,最好将每个 DDL 语句放在自己的变更集中,以防万一失败。事实上,如果您对现有数据库运行 generateChangeLog 命令,您会发现 Liquibase 会为每个 DDL 命令生成一个变更集。但是,您仍然应该对其他类型的命令进行事务级恢复,例如插入等。

于 2012-12-04T21:56:31.657 回答