Приходилось ли работать с триггерами в базах данных?
Что проверяют
Понимаете ли вы, что триггер это код, который выполняется внутри вашей транзакции, но живёт вне вашего репозитория. И умеете ли объяснить, когда он уместен, а когда логике лучше остаться в приложении.
Как отвечать
Коротко про механику: триггер привязан к таблице и событию, бывает BEFORE, AFTER и INSTEAD OF для представлений, срабатывает на строку или на оператор. В PostgreSQL тело выносится в функцию, возвращающую trigger, а CREATE TRIGGER только связывает её с таблицей, в MySQL тело пишется прямо в объявлении. Внутри доступны OLD и NEW.
Уместные задачи: журнал изменений и аудит, проставление технических полей, поддержка денормализованного счётчика, запрет операции, которую не выразить ограничением, запись события в таблицу исходящих сообщений.
Со стороны Java назовите последствия. Триггер работает в той же транзакции, его ошибка откатывает исходную операцию. Hibernate о сделанных триггером изменениях не знает: сущность в контексте остаётся прежней, пока её не перечитать, а поля, которые заполняет база, надо помечать соответствующими аннотациями. Триггер, меняющий число затронутых строк, ломает пакетные операции Hibernate ошибкой о неожиданном количестве строк.
Где спотыкаются
Пишут в триггере бизнес-логику и не проверяют переход состояния. Типичный пример из заготовленных ответов: при обновлении заказа со статусом «отправлен» триггер уменьшает остаток, но не сравнивает OLD.status с NEW.status. Любое повторное сохранение той же строки списывает товар ещё раз.
Забывают про стоимость. Построчный триггер с запросами внутри превращает массовое обновление в тысячи мелких операций, и всё это в одной транзакции, с блокировками до самого конца.
Прячут логику от команды. Триггера нет ни в коде, ни в ревью, и разработчик неделю ищет, кто меняет данные за его спиной. Лечится тем же, чем и схема: миграции в репозитории, упоминание в документации, а не правка руками на живой базе.