В HSQL для изменения КОНТРОЛЯ ТРАНЗАКЦИЙ не может быть активных транзакций . Flyway, в свою очередь, после фиксации миграции X и перед выполнением SQL из миграции X устанавливает autocommitt = false и выполняет некоторые из своих собственных операторов. Таким образом, если миграция содержит оператор SET DATABASE TRANSACTION CONTROL
, он будет ждать, пока эти незафиксированные операторы навсегда приведут к зависанию приложения.
(Боковое примечание: операторы, выполняемые flyway перед миграцией, варьируются от версии к версии, например, в 1.7, которые были чистыми выборками, поэтому переход с LOCK на MVCC был возможен, но после того, как у меня был MVCC, любые последующие операторы DDL в дальнейших миграциях зависли; в flyway 2.0 это было выберите для обновления в таблице schema_version, чтобы любое изменение управления транзакцией зависло; в 2.2 выбор для обновления был изменен на явную блокировку с тем же эффектом, что и в 2.0)
Таким образом, в принципе невозможно изменить управление транзакциями при миграциях на пролетном пути. С другой стороны, переход не поощряет внесение изменений, выходящих за рамки его миграции. Есть идеи, как изменить управление транзакциями с помощью flyway / hsql?
Обновление. Еще одно наблюдение: если для управления базой данных задано значение MVCC, то любой оператор DDL в миграции на пролетном пути также зависает в приложении. Поэтому я бы просто установил БЛОКИРОВКИ перед каждой миграцией и восстановил бы 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);
}
}