Получение от 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} < ${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} < ${db.live.output}/${build.dbdeploy.undofile}"
dir="${project.basedir}"
checkreturn="true" />
</catch>
</trycatch>
Вы действительно должны взглянуть на Капистрано. TomTom: вы что-то здесь упускаете: необходимо сделать резервную копию перед изменением схемы, но что делать с НОВЫМИ данными, которые были вставлены, пока вы думали, что все в порядке? Я не говорю, что есть хороший инструмент для решения этой проблемы, но проблема существует в реальной жизни.
Почему бы не написать серию отказов и добавить phing-задачу, которая запускается при сбое другой задачи?
"Правильный" способ сделать это - сделать резервную копию перед изменением схемы, а затем выполнить откат в случае ошибки.
Вы не говорите, какую базу данных вы используете, но мне было бы интересно, если бы все изменения схемы были поддержаны в транзакциях. В большинстве случаев базы данных SQL (oracle, db2, sql server) не делают этого во всех случаях по очень веским причинам. Трансацитональные изменения схемы ДЕЙСТВИТЕЛЬНО трудны и ДЕЙСТВИТЕЛЬНО интенсивны.