Транзакции Liquibase не работают в среде Spring

Я использую Liquibase в проекте со средой Spring. Однако функция отката, похоже, не работает.

Я подозреваю, что функция отката не поддерживается при использовании Spring для запуска Liquibase, поскольку в руководстве говорится:

LiquiBase позволяет вам отменить изменения, внесенные в вашу базу данных, либо автоматически, либо с помощью настраиваемого SQL отката. Поддержка отката доступна в командной строке, Ant, Maven и Grails.

Однако трудно поверить, что откат невозможен в этой настройке. Возникает вопрос: почему не работают откаты и как заставить откаты работать?


РЕДАКТИРОВАТЬ:

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

Я попытался использовать транзакции (как я полагаю, они есть), но это не дало желаемого эффекта.

Пример набора изменений, который пойдет не так:

<changeSet runInTransaction="true">
    <createTable tableName="table1">
        <column name="a" type="int"/>
    </createTable>
    <createTable tableName="table1">
        <column name="a" type="int"/>
    </createTable>
    <createTable tableName="table2">
        <column name="a" type="int"/>
    </createTable>
</changeSet>

Когда я запускаю пример набора изменений, Liquibase удается создать table1, но когда он пытается создать другую таблицу с тем же именем, он терпит неудачу (очевидно). Созданная таблица не удаляется и сохраняется в базе данных.

Просматривая руководство по Liquibase, я замечаю, что:

runInTransaction

Следует ли запускать changeSet как одну транзакцию (если возможно)? По умолчанию true. Предупреждение: будьте осторожны с этим атрибутом. Если установлено значение false и ошибка возникает на этапе выполнения changeSet, содержащего несколько операторов, таблица журнала изменений базы данных LiquiBase останется в недопустимом состоянии. Начиная с версии 1.9

Я использую MySQL, но набор изменений также должен работать с MSSQL и Oracle.

Я также использую транзакции Spring, и они отлично работают, есть идеи о том, как получить одновременно великолепие Liquibase и эти потрясающие (независимые от базы данных) транзакции?


person siebz0r    schedule 04.12.2012    source источник


Ответы (2)


Насколько я помню, весенняя интеграция предназначена для миграции базы данных в качестве этапа постобработки. Поскольку интерактивного шага нет, у вас не будет возможности указать команду, например «откатить одну ревизию».

Для интерактивных шагов, таких как откат n-изменений, вам потребуется использовать интерфейс командной строки или сценарий сборки через Ant или Maven.

ПОСЛЕ РЕДАКТИРОВАНИЯ

Откаты на уровне транзакции зависят от базовой реализации базы данных. Некоторые, например Oracle, не позволяют выполнять откат команд DDL (таких как создание таблицы) во время отката транзакции. Я обнаружил, что для этих случаев лучше всего помещать каждый оператор DDL в свой собственный набор изменений на случай, если один из них выйдет из строя. Фактически, если вы запустите команду generateChangeLog для существующей базы данных, вы обнаружите, что Liquibase генерирует набор изменений для каждой команды DDL. Тем не менее, у вас все еще должно быть восстановление на уровне транзакции для других типов команд, таких как вставки и т. Д.

person Peter Bratton    schedule 04.12.2012
comment
Я не правильно задал вопрос. Я исправил вопрос, пожалуйста, посмотрите мой измененный вопрос. - person siebz0r; 05.12.2012

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

Чтобы выполнить откат, вы можете использовать Liquibase jar следующим образом (см. Документы командной строки):

java -jar liquibase.jar \
      --driver=oracle.jdbc.OracleDriver \
      --classpath=website.war \
      --changeLogFile=com/example/db.changelog.xml \
      --url=jdbc:oracle:thin:@localhost:1521:oracle \
      --username=scott \
      --password=tiger \
      rollbackCount ?

JDBC-файл базы данных и журналы изменений должны быть доступны в WAR-файле.

person Mark O'Connor    schedule 04.12.2012
comment
Я не правильно задал вопрос. Я исправил вопрос, пожалуйста, посмотрите мой измененный вопрос. - person siebz0r; 05.12.2012