在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);
}
}
答案 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。