0

在 HSQL 中更改 TRANSACTION CONTROL不能有任何活动事务。反过来,Flyway 在提交迁移 X 之后和从迁移 X 执行 SQL 之前,设置 autocommitt=false 并执行它自己的一些语句。因此,如果迁移包含SET DATABASE TRANSACTION CONTROL语句,它将永远等待那些未提交的语句,从而导致应用程序挂起。

(旁注:flyway 在迁移之前执行的语句因版本而异,例如在 1.7 中是纯选择,因此从 LOCK 更改为 MVCC 是可能的,但是在我拥有 MVCC 之后,进一步迁移中的任何后续 DDL 语句都被挂起;在 flyway 2.0 中是在 schema_version 表上选择更新,因此任何事务控制更改都挂起;在 2.2 中选择更新已更改为显式锁定,与 2.0 中的效果相同)

所以基本上不可能在 flyway 迁移中更改事务控制。另一方面,flyway不鼓励迁移之外的变化。知道如何使用 flyway/hsql 更改事务控制吗?

更新 另一个观察结果是,当数据库控制设置为 MVCC 时,flyway 迁移中的任何 DDL 语句也会挂起应用程序。所以我会在每次迁移之前设置 LOCKS 并在之后恢复 MVCC。从 Flyway 的角度来看,这会是干净的解决方案吗?

import com.googlecode.flyway.core.util.jdbc.JdbcUtils;
public void migrate() {
    setDbTransactionControl("LOCKS");
    flyway.migrate();
    setDbTransactionControl("MVCC");
}

private void setDbTransactionControl(String mode) {
    Connection connection = null;
    try {
        connection = JdbcUtils.openConnection(ds);
        connection.createStatement().execute("SET DATABASE TRANSACTION CONTROL " + mode);
    } catch (SQLException e) {
        //log it
        JdbcUtils.closeConnection(connection);
    } finally {
        JdbcUtils.closeConnection(connection);
    }
}
4

2 回答 2

0

这在 Flyway 迁移中是不可能的。

在 Flyway 开始迁移之前,它会在单独的连接中打开一个事务以获取对其元数据表的锁定。因此,您将永远无法执行绝对必须在没有任何其他事务的情况下运行的语句。

您最好的选择可能是在数据源上设置它,这样它就可以在创建时以这种方式初始化每个连接。

于 2013-08-25T13:49:27.903 回答
0

尝试使用Flyway回调 beforeMigrateafterMigrate。两者都与迁移事务分开运行。MVCC 应该用于我的应用程序,因此 JDBC URL 包含hsqldb.tx=mvcc. 我可以在 Flyway 迁移期间使用beforeMigrate.sql SET DATABASE TRANSACTION CONTROL LOCKS;afterMigrate.sql 成功更改事务模型SET DATABASE TRANSACTION CONTROL MVCC;。也有 Java 版本的回调。我正在使用 HSQLDB 2.3.3 和 Flyway 3.2.1。

于 2016-09-01T14:54:46.197 回答