使用hsql更改flyway中的DB事务控制

时间:2013-08-23 13:24:28

标签: sql transactions hsqldb flyway mvcc

在HSQL中更改TRANSACTION CONTROL there can't be any active transactions。 反过来,Flyway在提交迁移X之后和从迁移X执行SQL之前,设置autocommitt = false并执行一些自己的语句。因此,如果迁移包含SET DATABASE TRANSACTION CONTROL语句,它将等待那些未提交的语句永远导致应用程序挂起。

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

所以基本上不可能在飞路迁移中改变交易控制。另一方面,飞路discourages changes outside of its migration。不知道怎么用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);
    }
}

2 个答案:

答案 0 :(得分:0)

在Flyway迁移中无法做到这一点。

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

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

答案 1 :(得分:0)

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