首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Oracle DDLs的Liquibase幂等性

Oracle DDLs的Liquibase幂等性
EN

Stack Overflow用户
提问于 2012-12-30 23:41:02
回答 1查看 1.6K关注 0票数 6

我正在研究如何在使用Oracle的新项目中使用Liquibase,我想知道如何确保我的changeSets足够健壮,能够在不需要人工干预的情况下从任何类型的故障中恢复过来。理想情况下,我应该使用runInTransaction属性,它允许在失败时回滚DDL,但是Oracle自动提交DDL。针对这种情况,文件建议:

因此,通常最好每个changeSet只进行一次更改,除非需要将一组非自动提交的更改应用于事务,例如插入数据。

每个changeSet拥有一个DDL会减少出现问题的可能性,但并不能消除它们。如果DDL成功了,但是DATABASECHANGELOG的更新失败了,从我的测试来看,Liquibase就会卡住,需要手动干预。

是否有必要在每一步中使用先决条件来避免这一问题?这使得产生的changeSets相当冗长。这是Liquibase示例表定义之一:

代码语言:javascript
复制
<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>

要使这种幂等性变为幂等性,我认为它必须改为如下所示:

代码语言:javascript
复制
<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能够产生这些先决条件。

谢谢

EN

回答 1

Stack Overflow用户

发布于 2013-05-03 19:46:00

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

在哪些情况下更新数据库变更日志失败了?我很好奇,因为这个应该很结实。

无论如何,您可以通过为Liquibase编写一个小的扩展来避免重复,这个扩展会自动完成所有更改集的操作。看看前提条件扩展点。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14095846

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档