【问题标题】:Liquibase partially rolling back a changesetLiquibase 部分回滚变更集
【发布时间】:2016-04-12 22:48:25
【问题描述】:

我正在尝试测试一个简单的 liquibase 变更集(如下)。

这是应用启动后运行的第二个变更日志。

我编写了一个故意的错误,我尝试创建列“NEW_2”两次以强制回滚变更集中的所有条目:ADD_COL_2

但是,即使生成了回滚文件并且我看到了:

INFO 16 年 4 月 13 日上午 12:17:liquibase:类路径:db/changelog/db.changelog-multi-set-then-rollback.xml:类路径:db/changelog/db.changelog-multi-set- then-rollback.xml::ADD_COL_2::USER1: 回滚变更集:classpath:db/changelog/db.changelog-multi-set-then-rollback.xml::ADD_COL_2::USER1

INFO 16 年 4 月 13 日上午 12:17:liquibase:类路径:db/changelog/db.changelog-multi-set-then-rollback.xml:类路径:db/changelog/db.changelog-multi-set- then-rollback.xml::ADD_COL_1::USER1: 回滚变更集:classpath:db/changelog/db.changelog-multi-set-then-rollback.xml::ADD_COL_1::USER1

在日志中,只有 NEW_4 和 NEW_5 列创建被回滚。

ADD_COL_2 更改日志未出现在 DATABASECHANGELOG 中。

ADD_COL_1 更改日志确实出现在 DATABASECHANGELOG 中。

为了测试回滚是否有效,我对 TABLE_1 执行本机查询,我可以看到 NEW_1,2 的值。我只希望看到 NEW_1,因为 NEW_2 是失败变更集的一部分?

如果我还查询 INFORMATION_SCHEMA.TABLES,我会看到 NEW_1 和 NEW_2。

我尝试了无回滚标签、每个语句的显式回滚标签、组标签的组合,但都无济于事。 我试图将标签移动到它自己的变更集。

对我来说似乎正在发生的事情是直到失败的命令的所有更改都没有回滚。

我需要手动调用一些东西吗?我是否需要手动执行回滚文件,我是否误解了 liquibase 的工作原理,它在失败时不是自动的???

我真的在我的智慧尽头,我(认为)我已经运行了所有可能的组合..我希望我在做一些愚蠢的事情!

非常感谢任何帮助!

我正在使用 Spring 版本 4.1.7、Liquibase 3.4.2 并在 Junit 中运行测试。

变更集:问题 ADD_COL_2 未完全回滚,NEW_2 列仍保留在 TABLE_1 中

    <changeSet id="ADD_COL_1" author="USER1" failOnError="true">
    <comment>Add column NEW_1 to TABLE_1</comment>
    <tagDatabase tag="ADD_COL_1"/>
    <addColumn tableName="TABLE_1">
        <column name="NEW_1" type="varchar(10)" value="NEW_1"/>
    </addColumn>
</changeSet>

<changeSet id="ADD_COL_2" author="USER1" failOnError="true">
    <tagDatabase tag="ADD_COL_2"/>
    <comment>Add column NEW_2 to TABLE_1</comment>
    <addColumn tableName="TABLE_1">
        <column name="NEW_2" type="varchar(10)" value="NEW_2"/>
    </addColumn>

    <comment>Add column NEW_3 to TABLE_1</comment>
    <addColumn tableName="TABLE_1">
        <column name="NEW_2" type="varchar(10)" value="NEW_3"/>
    </addColumn>

    <comment>Add column NEW_4 to TABLE_1</comment>
    <addColumn tableName="TABLE_1">
        <column name="NEW_4" type="varchar(10)"/>
    </addColumn>

    <comment>Add column NEW_5 to TABLE_1</comment>
    <addColumn tableName="TABLE_1">
        <column name="NEW_5" type="varchar(10)"/>
    </addColumn>

    <rollback>
        <dropColumn tableName="TABLE_1" columnName="NEW_2"/>
        <dropColumn tableName="TABLE_1" columnName="NEW_3"/>
        <dropColumn tableName="TABLE_1" columnName="NEW_4"/>
        <dropColumn tableName="TABLE_1" columnName="NEW_5"/>
    </rollback>
</changeSet>

**************** 附加信息 ****************

更新在我的应用程序内部运行,不运行外部 liquibase 命令。

我的服务扩展了 SpringLiquibase 并在设置属性后自动执行。

【问题讨论】:

    标签: liquibase rollback changeset


    【解决方案1】:

    Liquibase 不会运行任何 &lt;rollback&gt; 部分,直到您要求它执行(使用 liquibase 命令)。它执行事务中的每个变更集,如果失败,它会尝试使用数据库事务引擎回滚该事务(这有一些限制,例如,如果您在 MySQL 中添加列 A 并且在同一事务中添加列 B 失败后,比 A 没有回滚,因为 MySql 在 DDL 语句之后提交)。

    【讨论】:

    • 所以在上面的例子中,我的脚本中途失败了。是否有我需要执行 inside 我的代码来运行回滚的 liquibase 命令/方法?为了确认一下,我假设所有更改都会自动回滚是不正确的?
    • 如果您在单个变更集中添加 5 列并且第二列失败,liquibase 会尝试回滚整个变更集,但是,正如我所说,mysql 不会回滚已添加的列,因为它们已提交。查看此页面:liquibase.org/documentation/rollback.html 了解如何在 Liquibase 中使用回滚。但我认为回滚在您的情况下也会失败,因为它会尝试删除尚未创建的列。为避免此问题,您应该在单独的变更集中创建每个列(也可以由 Liquibase 自动生成 addColumn 的回滚)。
    • 感谢您的信息,将尝试一下。
    • 看看这个页面:liquibase.org/bestpractices.html 它包含一些关于变更日志的有用建议。
    • 抱歉 dbf,我还没有机会尝试这个,因为其他事情已经成为优先事项,一旦我有机会充分尝试你的建议,我就记下这个问题。
    猜你喜欢
    • 1970-01-01
    • 2011-05-04
    • 2016-05-29
    • 2014-04-24
    • 2019-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多