Управление транзакциями Changin DB на пролетном пути с помощью hsql

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

person Lukasz Lichota    schedule 23.08.2013    source источник


Ответы (2)


Это невозможно внутри миграции Flyway.

Прежде чем Flyway начнет миграцию, он открывает транзакцию в отдельном соединении, чтобы получить блокировку своей таблицы метаданных. Таким образом, вы никогда не сможете выполнить оператор, который обязательно должен выполняться без каких-либо других транзакций.

Ваш лучший вариант - это, вероятно, установить его в источнике данных, чтобы он мог инициализировать каждое соединение таким образом при создании.

person Axel Fontaine    schedule 25.08.2013
comment
Спасибо, я обновил вопрос примером решения - как вы думаете, это правильно с точки зрения архитектуры Flyway? - person Lukasz Lichota; 26.08.2013

Попробуйте использовать обратные вызовы Flyway beforeMigrate и afterMigrate . Оба работают отдельно от транзакций миграции. Для моего приложения следует использовать MVCC, чтобы URL-адрес JDBC содержал 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.

person user2043553    schedule 01.09.2016