提问者:小点点

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


我使用LiquiBase3.4.1和MySQL56并通过spring boot运行Liquibase。

我有一个变更集,其中包括向现有表中添加一列。新的column具有valuecomputed属性,并带有一个简单的select。

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

变更集失败时,为什么Liquibase没有回滚事务?如何使变更集事务性化?

编辑:很明显,MySQL会在每个DDL命令之后提交。如果我在rollback标记中指定了rollback命令,那么在变更集失败的情况下,Liquibase会运行吗?


共1个答案

匿名用户

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

我不确定是否可以进行事务性操作,但您可以将其拆分为两个变更集,如果列填充失败,将回滚它,并且在重新运行之后,您将不会有任何问题(列已经添加到以前的变更集中)。

Ilya Novoseltsev编辑:

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

坏:

<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>

好:

<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。这些语句破坏了addcolumn原子性。它们在DDL命令之后作为单独的update命令执行。正确的方法是将它们移动到单独变更集中自己的update标记中。