Postgres允许使用CONCURRENTLY选项创建索引而不锁定表。事务中不允许使用此选项,因此当它添加到flyway迁移脚本时,flyway会失败:
错误:由org.postgresql.util.PSQLException引起:错误:CREATE INDEX CONCURRENTLY无法在事务块内运行
ActiveRecord支持disable_ddl_transaction!来解决此问题。 flyway是否支持某种方式在事务之外运行这样的脚本?
答案 0 :(得分:3)
这是在Flyway 4.1中实现的,请参阅票证851和Non-Transactional PostgreSQL Support in Flyway。
此功能通过检测应该在没有事务的情况下执行语句来工作。据我所知,目前只支持PostgreSQL。
第一个障碍是检测迁移何时需要在外部运行 交易前进的两条道路是明显的。第一条路,[..], 是创建文件名注释。第二条路径是添加一个 语句解析器到Flyway,检测非事务性命令和 在适当的隔离级别运行它们。尽管额外的工作 Boxfuse团队坚定不移地要求他们 遵循第二条道路。它为用户提供了更好的用户体验 从长远来看,Flyway用户。
默认情况下,以这种方式执行的迁移应该只包含需要在没有事务的情况下执行的语句。默认情况下,不允许将其与事务性语句混合,并且需要使用属性启用。
创建迁移不得与事务混合的条件 非事务性语句会产生可能引入的限制 未来用户看不见的问题。如果这个未知 需要通常在内部运行的DDL的情况 需要处理事务,称为属性 flyway.allowMixedMigrations 已添加到配置中。默认情况下为false。我强烈建议永远不要打开它。
非事务处理的语句由PostgreSQLSqlStatementBuilder
中的代码确定:
if (statementStart.matches("(CREATE|DROP) (DATABASE|TABLESPACE) .*")
|| statementStart.matches("ALTER SYSTEM .*")
|| statementStart.matches("(CREATE|DROP)( UNIQUE)? INDEX CONCURRENTLY .*")
|| statementStart.matches("REINDEX( VERBOSE)? (SCHEMA|DATABASE|SYSTEM) .*")
|| statementStart.matches("VACUUM .*")
|| statementStart.matches("DISCARD ALL .*")
|| statementStart.matches("ALTER TYPE .* ADD VALUE .*")
) {
executeInTransaction = false;
}
答案 1 :(得分:1)
不是在这一点上。所有迁移当前都在事务中运行。您可以在问题跟踪器中提交增强请求。
答案 2 :(得分:0)
根据这篇文章:
Flyway migration hangs for postgres CREATE INDEX CONCURRENTLY
您只需添加NT作为迁移的前缀即可
V201609121806__create_index_for_table.sql
成为
NTV201609121806__create_index_for_table.sql