首页 文章

Liquibase不会使用MySQL回滚失败的变更集

提问于
浏览
3

我正在使用Liquibase 3.4.1和MySQL56并通过Spring Boot运行Liquibase .

我有一个变更集,包括向现有表添加列 . 新的 column 具有 valueComputed 属性,具有简单的选择 .

当我在该选择中出错时,变更集失败并且迁移在该变更集处停止 . 但是新列被提交到数据库但没有正确的值,而且真正糟糕的是,这个变更集没有被标记为运行!下次我运行迁移时Liquibase尝试再次执行更改集,但由于已经创建了列而失败了 .

当变更集失败时,为什么Liquibase不回滚事务?如何进行变更集事务处理?

编辑:显然,MySQL在每个DDL命令后提交 . 如果我在rollback标签中指定回滚命令,那么Liquibase会在变更集失败的情况下运行吗?

1 回答

  • 5

    Liquibase尝试在事务中运行changeset,但我认为mysql在ddl之后提交(列添加):https://dev.mysql.com/doc/refman/5.5/en/implicit-commit.html

    我不确定是否可以进行事务处理,但是您可以将其拆分为两个更改集,如果列填充失败,它将被回滚,重新运行后您将不会遇到问题(列已在先前的更改集中添加) .

    编辑Ilya Novoseltsev:

    涉及DDL更改的变更集应该是原子的 .

    Bad

    <changeSet author="novoseltsevib (generated)" id="1445871764871-19">
        <addColumn tableName="account_range">
            <column name="cash2card_participation" type="BIT(1)" valueBoolean="false"/>
        </addColumn>
        <addColumn tableName="account_range_aud">
            <column name="cash2card_participation" type="BIT(1)"/>
        </addColumn>
    </changeSet>
    

    Good:

    <changeSet author="novoseltsevib (generated)" id="1445871764871-19">
        <addColumn tableName="account_range">
            <column name="cash2card_participation" type="BIT(1)" valueBoolean="false"/>
        </addColumn>
    </changeSet>
    <changeSet author="novoseltsevib (generated)" id="1445871764871-20">
        <addColumn tableName="account_range_aud">
            <column name="cash2card_participation" type="BIT(1)"/>
        </addColumn>
    </changeSet>
    

    以这种方式编写变更集允许重复失败的变更集,而不必担心部分提交的变更 .

    使用 value = ... 时应该小心,特别是 valueComputed . 这些语句破坏了原子性 . 它们在DDL命令之后作为单独的更新命令执行 . 正确的方法是在单独的变更集中将它们移动到自己的 update 标记中 .

相关问题