4.3.4. Выполнение скриптов БД сервером

Механизм выполнения скриптов сервером предназначен для приведения БД в актуальное состояние на старте сервера приложения, и активируется во время инициализации блока Middleware. Понятно, что при этом приложение должно быть собрано и развернуто на сервере, будь то собственный Tomcat разработчика или сервер в режиме эксплуатации.

Данный механизм в зависимости от описанных ниже условий выполняет либо скрипты создания, либо скрипты обновления, то есть он может и инициализировать БД с нуля, и обновлять ее. Однако, в отличие от описанной в предыдущем разделе задачи Gradle createDb, для выполнения инициализации базы она должна существовать - сервер не создает БД автоматически, а только прогоняет на ней скрипты.

Механизм выполнения скриптов сервером действует следующим образом:

  • Скрипты извлекаются из каталога скриптов базы данных, определяемого свойством приложения cuba.dbDir. В стандартном варианте развертывания в Tomcat это tomcat/webapps/app-core/WEB-INF/db.

  • Если в БД отсутствует таблица SEC_USER, то считается, что база данных пуста, и запускается полная инициализация с помощью скриптов создания БД. После выполнения инициализирующих скриптов их имена запоминаются в таблице SYS_DB_CHANGELOG. Кроме того, там же сохраняются имена всех доступных скриптов обновления, без их выполнения.

  • Если в БД имеется таблица SEC_USER, но отсутствует таблица SYS_DB_CHANGELOG (это случай, когда в первый раз запускается описываемый механизм на имеющейся рабочей БД), никакие скрипты не запускаются. Вместо этого создается таблица SYS_DB_CHANGELOG и в ней сохраняются имена всех доступных на данный момент скриптов создания и обновления.

  • Если в БД имеются и таблица SEC_USER и таблица SYS_DB_CHANGELOG, то производится запуск скриптов обновления, и их имена запоминаются в таблице SYS_DB_CHANGELOG. Причем запускаются только те скрипты, имен которых до этого не было в таблице SYS_DB_CHANGELOG, т.е. не запускавшиеся ранее. Последовательность запуска скриптов определяется двумя факторами: приоритетом базового проекта (см. содержимое каталога скриптов базы данных: 10-cuba, 20-workflow, …​) и именем файла скрипта (с учетом подкаталогов внутри каталога update) в алфавитном порядке.

    Перед выполнением скриптов обновления производится проверка, все ли скрипты создания схемы компонентов приложения выполнены (путем выборки из таблицы SYS_DB_CHANGELOG). Если обнаруживается, что БД не инициализирована для работы некоторого компонента, выполняются его скрипты создания.

Механизм выполнения скриптов на старте сервера включается свойством приложения cuba.automaticDatabaseUpdate.

В запущенном приложении механизм выполнения скриптов можно стартовать с помощью JMX-бина app-core.cuba:type=PersistenceManager, вызвав его метод updateDatabase() с параметром update. Понятно, что таким способом можно только обновить БД, а не проинициализировать новую, так как войти в систему для запуска метода JMX-бина при пустой БД невозможно. При этом следует иметь в виду, что если на старте Middleware или при входе пользователя в систему начнется инициализация той части модели данных, которая уже не соответствует устаревшей схеме БД, то произойдет ошибка, и продолжение работы станет невозможным. Именно поэтому универсальным является только автоматическое обновление БД на старте сервера перед инициализацией модели данных.

JMX-бин app-core.cuba:type=PersistenceManager имеет еще один метод, относящийся к механизму обновления БД: findUpdateDatabaseScripts(). Он возвращает список новых скриптов обновления, имеющихся в каталоге и не зарегистрированных в БД.

Практические рекомендации по использованию механизма обновления БД сервером приведены в Создание и обновление БД при эксплуатации приложения.