Потокобезопасные миграции Doctrine 2 / Symfony 2

sqlgrinder_icon_128x128В этой статье я раскрою сразу две темы. Первая тема – это потокобезопасные миграции в Doctrine 2, а второй будет каскадное исполнение команд в консоле Symfony 2. На самом деле, ко всему надо иметь прагматический подход. Вот например, касаясь той же симфонии, есть там кое-что, что мне определенно нарвится. В частности – это замечательная симфоневская консоль.

 

Потокобезопасные миграции.

Коротко эту тему я уже затронул в одной из предыдущих статей. В кластере находятся несколько веб-серверов и один сервере базы данных (MySQL). При этом происходит одновременный деплой кода на веб-серверах, и необходимо выполненеи миграции один (и только один раз) на одном из веб-серверов. Т.е. два потока должны разделять один ресурс. Как это сделать?

migrations

Будем использовать сервис глобальных блокировок, разработанный в предыдущей статье.

Каскадное исполнение команд в Symfony

У нас в app/console есть волжебная команда doctrine:migrations:migrate Нам необходимо обернуть её в обертку, которая будет смотреть а можно ли собственно накатывать мигарцию. Если ресурс свободен (нет другого потока) – то накатываем миграцию, а если ресурс занят, и нам не удаётся поулчить блокировку, тогда ничего не делаем. Ведь сейчас другой процесс как раз вовсю выполняет миграцию 🙂

Вот код волшебной оберточки.

My\DefaultBundle\Command\SafeMigrateCommand.php

 

Заключение

Собственно, вот и всё. Как видите создать команду-обертку для другой команды в Symfony 2 проще простого. Зато теперь можно не беспокоиться за целостность нашей базы данных.

P.S.

В замечательном средстве деплоя Capistrano для выполнения аналогичной операции предусмотрены специальные роли серверов. В частности, если мы имеем несколько серверов БД, то одного из них надо в конфиге назначить мастером вот так:

Тогда миграции будут выполняться только на нём.

Ссылки

The Console Component
Сapistrano, :db role, what’s it for?

4 Comments

    1. Вот как раз на всех и не нужно, но выполняется. Это особенность TeamCity. Если скажете, как можно указать, что определённую цель(target) выполнять на определённом build-agent буду премного благодарен.

  1. Я тоже не понял постановку задачи. Какие потоки? Кто их пораждает? Предложения не согласованы и суть не ясна. Первый абзац просто выносит.

    1. Имеется в виду вот этот бандл: http://symfony.com/doc/current/bundles/DoctrineMigrationsBundle/index.html
      Потоки порождает скрипт деплоя запущенный одновременно на нескольких серверах. Про первый абзац – это анонс имеется в виду. Там краткое описание двух тем. Не понимаю, что именно вынесло мозг.

Leave a Reply to Андрей Токарчук Cancel reply