Можно ли считать DDL автоматически откатываемым при ROLLBACK?
Нет. Откат DDL зависит от конкретной СУБД, вида команды и иногда от способа её выполнения: SQL-стандарт не гарантирует одинаковую транзакционность всех DDL-операций. Поэтому нельзя без проверки предполагать, что после ROLLBACK создание, изменение или удаление объекта схемы будет отменено.
DDL управляет структурой базы данных, тогда как DML изменяет данные. Транзакционная модель изначально ориентирована на атомарное выполнение изменений, но операции со схемой затрагивают метаданные, блокировки, системный каталог и иногда физическую организацию хранения.
Из-за различий в архитектуре СУБД одни реализации включают DDL в обычные транзакции, другие выполняют неявную фиксацию перед операцией или после неё, а отдельные команды имеют специальные ограничения. Поэтому поведение DDL стало частью конкретного диалекта и документации СУБД.
Разработчик может поместить изменение схемы и изменение данных в одну транзакцию, а затем рассчитывать, что ошибка автоматически вернёт базу к исходному состоянию. Если используемая DDL-команда не поддерживает откат или вызывает неявный COMMIT, структура схемы останется изменённой даже после попытки отменить транзакцию.
Это особенно опасно при миграциях: приложение может ожидать старую структуру, а база уже использовать новую. Дополнительный риск возникает при частично выполненной последовательности DDL, когда последующие команды работают с уже изменёнными объектами.
Сначала нужно установить три свойства: поддерживает ли СУБД транзакционный DDL, относится ли конкретная команда к поддерживаемым, и не выполняет ли клиент или инструмент миграций неявную фиксацию. Наличие слова ALTER, CREATE или DROP само по себе ничего не доказывает.
Например, в PostgreSQL обычные операции создания и изменения объектов обычно участвуют в транзакции:
После отката в PostgreSQL таблица demo обычно не существует. Это пример поведения конкретной СУБД, а не универсальное свойство SQL. В других системах часть DDL может выполнять неявную фиксацию; кроме того, даже в транзакционной СУБД отдельные команды могут быть исключениями.
DROP и ALTER могут требовать сильных блокировок, поэтому транзакционный откат не означает отсутствия влияния на работающую систему: до завершения транзакции другие сеансы могут ждать или видеть особенности блокировок. Также откат логической операции не обязательно означает мгновенное освобождение всех физических ресурсов.
Надёжная миграция должна явно учитывать диалект СУБД, проверять DDL на тестовом экземпляре и выбирать стратегию совместимости приложения. Если операция неоткатываемая, миграцию разбивают на безопасные этапы, делают обратимую смену там, где это возможно, и отдельно планируют восстановление.
Команда добавляет новый обязательный столбец в рабочую таблицу. Вариант с одной большой транзакцией удобен: при поддержке транзакционного DDL можно отменить всю миграцию, но длительные блокировки могут остановить запросы. Вариант с отдельными командами уменьшает продолжительность блокировок, однако при неявной фиксации промежуточное состояние невозможно автоматически отменить.
Практичное решение — поэтапная миграция: сначала добавить столбец в совместимом виде, затем обновить приложение, заполнить данные контролируемыми порциями и только после проверки установить строгие ограничения. Такой подход не полагается на автоматический откат DDL, снижает риск простоя и позволяет отдельно откатить версию приложения или выполнить компенсирующее изменение схемы.
Нет. Успешное выполнение команды означает лишь, что СУБД приняла её, но не гарантирует участие в текущей транзакции. Команда могла автоматически зафиксировать изменения или вообще выполняться вне транзакционного контекста. Проверять нужно документацию конкретной СУБД и фактическое поведение в тестовой транзакции.
Нет. Длинная транзакция удерживает блокировки и версии метаданных, может задерживать другие операции и увеличивать объём служебных данных. Даже полностью откатываемая миграция способна создать заметную нагрузку и временную недоступность объектов.
Нет, если отличаются версия СУБД, параметры, драйвер, инструмент миграций или конкретные DDL-команды. Клиент может автоматически завершать транзакцию, а разные команды одного класса могут иметь разные ограничения. Проверка должна соответствовать реальному стеку и включать сценарии ошибки, блокировок и частичного выполнения.