我正在研究如何在使用Oracle的新项目中使用Liquibase,我想知道如何确保我的changeSets足够健壮,能够在不需要人工干预的情况下从任何类型的故障中恢复过来。理想情况下,我应该使用runInTransaction属性,它允许在失败时回滚DDL,但是Oracle自动提交DDL。针对这种情况,文件建议:
因此,通常最好每个changeSet只进行一次更改,除非需要将一组非自动提交的更改应用于事务,例如插入数据。
每个changeSet拥有一个DDL会减少出现问题的可能性,但并不能消除它们。如果DDL成功了,但是DATABASECHANGELOG的更新失败了,从我的测试来看,Liquibase就会卡住,需要手动干预。
是否有必要在每一步中使用先决条件来避免这一问题?这使得产生的changeSets相当冗长。这是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能够产生这些先决条件。
谢谢
发布于 2013-05-03 19:46:00
不幸的是,在大多数RDBMS中,DDL语句提交事务,Liquibase通过回滚事务来响应失败。因此,首先,我要做的是将每个DDL语句包装在一个单独的变更集中。
在哪些情况下更新数据库变更日志失败了?我很好奇,因为这个应该很结实。
无论如何,您可以通过为Liquibase编写一个小的扩展来避免重复,这个扩展会自动完成所有更改集的操作。看看前提条件扩展点。
https://stackoverflow.com/questions/14095846
复制相似问题