Получение от Phing задачи dbdeploy для автоматического отката при ошибке дельты

Я использую задачу Phing dbdeploy для управления моей схемой базы данных. Это работает нормально, пока нет ошибок в запросах моих дельта-файлов.

Однако в случае ошибки dbdeploy просто запустит дельта-файлы до запроса с ошибкой, а затем прервет работу. Это вызывает у меня некоторое разочарование, потому что я должен вручную откатить запись в таблице изменений. Если я этого не сделаю, dbdeploy предположит, что миграция прошла успешно при следующей попытке, поэтому любые повторные попытки ничего не сделают.

Итак, вопрос в том, есть ли способ получить транзакции использования dbdeploy или вы можете предложить какой-либо другой способ автоматического отката phing при возникновении ошибки?

Примечание: я не очень хорошо разбираюсь в Phing, поэтому, если это включает в себя написание пользовательского задания, любой пример кода или URL с дополнительной информацией высоко ценится. Спасибо

6 ответов

Решение

(если вы все еще там...) Что касается phing для задачи db dump, используйте утилиту db dump и создайте задачу phing. Я использую главным образом postgres и у меня есть это в моем phing build.xml:

<target name="db-dump" depends="">
    <php expression="date('Ymd-Hi')" returnProperty="phing.dump.ts"/>
    <exec command="pg_dump -h ${db.host} -U ${db.user} -O ${db.name} | gzip > ${db.dumppath}/${db.name}-${phing.dump.ts}.gz" />
</target>

Самый простой способ решения вашей проблемы - использовать задачу pdoexec, которая по умолчанию запускает сценарий sql в транзакции. При возникновении ошибки ядро ​​базы данных автоматически откатит ваши изменения (даже те, которые внесены в таблицу журнала изменений - база данных будет в предыдущем состоянии)

Пример:

<pdosqlexec 
    url="pgsql:host=${db.host}
    dbname=${db.name}"
    userid="${db.user}"
    password="${db.pass}"
    src="${build.dbdeploy.deployfile}"
/>

Я знаю, что это очень старая тема, но, возможно, она будет использоваться полностью для кого-то еще. Вы можете использовать операторы try->catch, чтобы реализовать решение для этого. Мой пример:

<trycatch>
    <try>
        <exec
            command="${progs.mysql} -h${db.live.host} -u${db.live.user} -p${db.live.password} ${db.live.name} &lt; ${db.live.output}/${build.dbdeploy.deployfile}"
            dir="${project.basedir}"
            checkreturn="true" />
            <echo>Live  database was upgraded successfully</echo>
    </try>    
    <catch>
            <echo>Errors in upgrading database</echo>
            <exec
            command="${progs.mysql} -h${db.live.host} -u${db.live.user} -p${db.live.password} ${db.live.name} &lt; ${db.live.output}/${build.dbdeploy.undofile}"
            dir="${project.basedir}"
            checkreturn="true" />
    </catch>
    </trycatch>

Вы действительно должны взглянуть на Капистрано. TomTom: вы что-то здесь упускаете: необходимо сделать резервную копию перед изменением схемы, но что делать с НОВЫМИ данными, которые были вставлены, пока вы думали, что все в порядке? Я не говорю, что есть хороший инструмент для решения этой проблемы, но проблема существует в реальной жизни.

Почему бы не написать серию отказов и добавить phing-задачу, которая запускается при сбое другой задачи?

"Правильный" способ сделать это - сделать резервную копию перед изменением схемы, а затем выполнить откат в случае ошибки.

Вы не говорите, какую базу данных вы используете, но мне было бы интересно, если бы все изменения схемы были поддержаны в транзакциях. В большинстве случаев базы данных SQL (oracle, db2, sql server) не делают этого во всех случаях по очень веским причинам. Трансацитональные изменения схемы ДЕЙСТВИТЕЛЬНО трудны и ДЕЙСТВИТЕЛЬНО интенсивны.

Другие вопросы по тегам