lus*_*uso 5 mysql database liquibase
在MySQL上使用liquibase v3.6.3。如果我理解正确,默认情况下,每个CHANGESET都会运行到SQL事务中。但是,在我看来,事务是在CHANGE基础上提交的。运行此脚本时
databaseChangeLog:
- changeSet:
id: changeset-
changes:
- renameTable:
oldTableName: old_table
newTableName: new_table
- addColumn:
columns:
- column:
name: test_column_name
type: varchar(255)
tableName: other_table
Run Code Online (Sandbox Code Playgroud)
如果addColumn标记由于某些SQL异常(例如约束检查或其他)而失败,则由于变更集失败,因此不会更改databasechangelog表,这是我不希望的。但是,firs语句DID通过了,我的表现在称为new_table。
当然,如果我纠正了导致第二个失败并重试更新的问题,则它将失败,因为old_table不再存在。
我知道liquibase文档中的这一段
Liquibase尝试执行最后提交的事务中的每个changeSet,如果有错误,则回滚。一些数据库将自动提交语句,这会干扰此事务的设置并可能导致意外的数据库状态。因此,通常最好每个changeSet仅包含一个更改,除非您希望将一组非自动提交的更改应用为事务(例如插入数据)。
https://www.liquibase.org/documentation/changeset.html
但我不太了解。自动提交是指自动提交交易。如果所有变更集都包装在事务中,为什么只传递一些变更?liquibase是否应回滚整个交易?
有什么最佳实践吗?我们不能在liquibase中手动设置交易吗?
部分提交变更集的不是 Liquibase。我使用过许多数据库,我使用的所有数据库的一个基本概念是,事务仅结合数据修改 (DML)。
DDL 永远不是事务的一部分。它总是立即执行,并在执行之前自动提交打开的事务。原因是数据库的回滚命令只能处理数据修改。它无法处理 DDL。如果回滚不再可能,那么保持事务打开就没有用了。
因此,Liquibase 确实创建了一个事务并在最后提交了所有更改,如文档所述。但这只有在变更集仅包含 DML 而没有 DDL 时才有效。
因为 DDL 和 DML 永远不应该混合在一个变更集中,每个 DDL 语句都应该在一个单独的变更集中。否则,Liquibase 无法防止变更集部分成功并在尝试回滚时造成麻烦。