gpt4 book ai didi

oracle - Oracle DDL 上的 Liquibase 幂等性

转载 作者:行者123 更新时间:2023-12-03 15:02:20 26 4
gpt4 key购买 nike

我正在研究将 Liquibase 用于使用 Oracle 的新项目,我想知道如何确保我的变更集足够健壮,无需人工干预即可从任何类型的故障中恢复。理想情况下,我会使用 runInTransaction 属性,这将允许 DDL 在失败时回滚,但 Oracle 会在 DDL 上自动提交。对于这种情况,文档建议:

因此,通常最好每个更改集只有一个更改,除非您希望将一组非自动提交更改应用为事务(例如插入数据)。

每个变更集有一个 DDL 会减少出现问题的机会,但不会消除它们。如果 DDL 成功,但对 DATABASECHANGELOG 的更新失败,从我的测试来看,Liquibase 似乎卡住了,需要手动干预。

有必要在每一步都使用前提条件来避免这个问题吗?这使得生成的更改集非常冗长。这是 Liquibase 示例表定义之一:

<changeSet author="jsmith" id="1">
<createTable tableName="departments"
remarks="The departments of this company. Does not include geographical divisions.">
<column name="id" type="number(4,0)">
<constraints nullable="false" primaryKey="true"
primaryKeyName="DPT_PK"/>
</column>
<column name="dname" type="varchar2(14)"
remarks="The official department name as registered on the internal website."/>
</createTable>
<addUniqueConstraint constraintName="departments_uk1"
columnNames="dname" tableName="departments"/>
<createSequence sequenceName="departments_seq"/>
</changeSet>

为了使这个幂等,我认为它必须更改为如下所示:
<changeSet author="jsmith" id="1">
<preConditions onFail="MARK_RAN">
<not>
<tableExists tableName="departments" />
</not>
</preConditions>
<createTable tableName="departments"
remarks="The departments of this company. Does not include geographical divisions.">
<column name="id" type="number(4,0)" / column>
<column name="dname" type="varchar2(14)"
remarks="The official department name as registered on the internal website." />
</createTable>
</changeSet>

<changeSet author="jsmith" id="2">
<preConditions onFail="MARK_RAN">
<not>
<primaryKeyExists primaryKeyName="pk_departments" />
</not>
</preConditions>
<addPrimaryKey tableName="departments" columnNames="id"
constraintName="pk_departments" />
</changeSet>

<changeSet author="jsmith" id="3">
<preConditions onFail="MARK_RAN">
<not>
<uniqueConstraintExists constraintName="departments_uk1" />
</not>
</preConditions>
<addUniqueConstraint constraintName="departments_uk1"
columnNames="dname" tableName="departments" />
</changeSet>

<changeSet author="jsmith" id="4">
<preConditions onFail="MARK_RAN">
<not>
<sequenceExists sequenceName="departments_seq" />
</not>
</preConditions>
<createSequence sequenceName="departments_seq" />
</changeSet>

有没有更简单的方法来实现这一目标?我原以为 Liquibase 能够产生这些先决条件。

谢谢

最佳答案

不幸的是,在大多数 RDBMS 中,DDL 语句提交事务,而 Liquibase 仅通过回滚事务来应对失败。所以首先我要做的是将每个 DDL 语句包装在一个单独的变更集中。

在哪些情况下更新databaschangelog 失败?我很好奇,因为这应该非常健壮。

无论如何,您可以通过为 Liquibase 编写一个小扩展来避免重复自己,该扩展会自动为您的所有变更集执行此操作。看看Precondition延伸点。

关于oracle - Oracle DDL 上的 Liquibase 幂等性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14095846/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com