6

私は、Oracle を使用する新しいプロジェクトで Liquibase を使用して調査しています。変更セットが、手動の介入なしであらゆる種類の障害から回復するのに十分なほど堅牢であることを確認するにはどうすればよいか疑問に思っています。理想的には、失敗時に DDL をロールバックできる runInTransaction 属性を使用しますが、Oracle は DDL を自動コミットします。この状況では、ドキュメントでは次のことを推奨しています。

したがって、通常は、データの挿入などのトランザクションとして適用する非自動コミット変更のグループがない限り、changeSet ごとに変更を 1 つだけ持つことが最善です。

changeSet ごとに 1 つの DDL を使用すると、問題が発生する可能性は低くなりますが、問題がなくなるわけではありません。DDL は成功するが、DATABASECHANGELOG への更新が失敗する場合、私のテストでは、Liquibase が動かなくなり、手動の介入が必要になるようです。

この問題を回避するには、各ステップで前提条件を使用する必要がありますか? これにより、結果の changeSet が非常に冗長になります。これは、Liquibase のテーブル定義の例の 1 つです。

<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 がこれらの前提条件を生成できると考えていたでしょう。

ありがとう

4

1 に答える 1

0

残念ながら、ほとんどの RDBMS では、DDL ステートメントはトランザクションをコミットし、Liquibase はトランザクションをロールバックするだけで失敗に反応します。したがって、最初に行うことは、各 DDL ステートメントを個別の変更セットにラップすることです。

どのような場合に、databaschangelog の更新が失敗しましたか? これはかなり堅牢なはずなので、私は興味があります。

とにかく、すべての変更セットに対して自動的に行う Liquibase の小さな拡張機能を作成することで、繰り返しを避けることができます。Precondition拡張ポイントを見てください。

于 2013-05-03T19:46:00.427 に答える