【问题标题】:Liquibase changesets only executing as a single transactionLiquibase 变更集仅作为单个事务执行
【发布时间】:2017-09-17 18:37:31
【问题描述】:

discussion at the Liquibase forums 中,开发人员 Nathan Voxland 说 Liquibase 应该在每个变更集之后提交。我知道这是一个七年前的主题,所以从那时起可能发生了很多变化,但也许不会?

它应该在 changeSet 之后提交。在大多数数据库中,addColumn 也会自动提交。

changeSet tag 的文档可以解释为“在变更日志中的所有先决条件成功后提交”,这与 7 年前的帖子相矛盾。

Liquibase 尝试在最后提交的事务中执行每个 changeSet,如果出现错误则回滚。一些数据库会自动提交语句,这会干扰此事务设置并可能导致意外的数据库状态。因此,通常最好每个 changeSet 只进行一次更改,除非您希望将一组非自动提交更改应用为事务,例如插入数据。

Liquibase 是否仍然意味着在每个变更集之后提交?

我正在使用带有 Netbeans/Maven 的 Liquibase 3.5.3 并使用 Java 代码开始更新。

我有一个 main_changelog 文件,它的唯一目的是将所有更改日志包含在一个目录中。该目录中的两个(目前)变更日志各有两个变更集。两个变更日志在其变更集之外都有一个 onFail="HALT" 前提条件。

我的测试环境具有 changelog_1 成功的前提条件(因此其中的所有变更集都将被执行),而 changelog_2 前提条件失败。

我看到的是,在这个全新的数据库上,DATABASECHANGELOG 表已创建但为空。没有任何变更集被提交,大概是因为后来的前提条件 HALTS 失败。我期待所有直到 HALT 的变更集都被提交。

按预期工作?还是错误?

【问题讨论】:

  • Liquibase 可能会或可能不会将事务用于单个变更集。默认是使用事务。但我从未读过或目睹任何表明事务边界可能超出变更集边界的内容,并且当任何事情失败时可能会回滚多个变更集。如果未应用您的第一个变更集,则前提条件有问题,或者由于错误而无法应用。你能提供 liquibase 的输出吗?
  • 这取决于您使用的 DBMS。如果 DBMS 支持事务 DDL,那么每个 changeSet 都会被提交。如果没有,那么每个 change 都会被提交
  • 感谢您的回复。解决方案最终是将前提条件包装在自己的变更集中。现在,当它失败时,它会保留之前的所有变更集并停止其下方的所有内容。

标签: java maven netbeans transactions liquibase


【解决方案1】:

来自 liquibase 文档:

变更日志级别的前提条件适用于所有变更集,而不仅仅是 当前变更日志或其子变更日志中列出的内容。

因为您的前提条件是变更日志级别并且您已指定 HALT,所以 liquibase 不会应用任何变更集。交易性从来没有真正发挥作用。

【讨论】:

  • 谢谢。这导致解决我的问题。我将我的先决条件包装在它自己的 changeSet 中,所以现在当它失败时,它会停止它下面的所有内容并保留它之前的所有内容。
【解决方案2】:

如文档中所述,每个 changeSet 都有一个单独的事务

Liquibase 尝试执行事务中的每个变更集 ...

https://docs.liquibase.com/concepts/basic/changeset.html

【讨论】:

    猜你喜欢
    • 2014-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-05
    • 1970-01-01
    • 2019-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多