Changin DB transaction control in flyway with hsql

空扰寡人 提交于 2019-12-25 03:14:08

问题


In HSQL to change TRANSACTION CONTROL there can't be any active transactions. Flyway, in turn, after committing migration X and before executing SQL from migration X, sets autocommitt=false and executes some of its own statements. So if the migration contains SET DATABASE TRANSACTION CONTROL statement it will wait for those uncommitted statements forever causing application to hang.

(Side note: The statements executed by flyway before migration varies from version to version e.g. in 1.7 that were pure selects so changing from LOCK to MVCC was possible but after I had MVCC any subsequent DDL statements in further migrations hanged; in flyway 2.0 it was select for update on schema_version table so any transaction control change hanged; in 2.2 select for update was changed to explicit lock with the same effect as in 2.0)

So basically it is not possible to change transaction control in flyway migrations. On the other hand flyway discourages changes outside of its migration. Any idea then how to change transaction control in with flyway/hsql?

Update Another observation is that when database control is set to MVCC then any DDL statement in flyway migration hangs application too. So I would just set LOCKS before each migration and restore MVCC after it. Would that be clean solution from Flyway perspective?

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);
    }
}

回答1:


This is not possible inside a Flyway migration.

Before Flyway starts a migration, it opens a transaction in a separate connection to acquire a lock on its metadata table. So you will never be able to execute a statement that absolutely must be run without any other transactions.

Your best option is probably to set it on the datasource, so it can init each connection this way upon create.




回答2:


Try to use the Flyway callbacks beforeMigrate and afterMigrate. Both run apart from the migration transactions. MVCC should be used for my application so the the JDBC URL contains hsqldb.tx=mvcc. I could sucessfully change the transaction model during the Flyway migration with beforeMigrate.sql SET DATABASE TRANSACTION CONTROL LOCKS; and afterMigrate.sql SET DATABASE TRANSACTION CONTROL MVCC;. There are also Java versions of the callbacks. I'm using HSQLDB 2.3.3 and Flyway 3.2.1.



来源:https://stackoverflow.com/questions/18403998/changin-db-transaction-control-in-flyway-with-hsql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!