Я работаю над программой, которая выдает DDL. Я хотел бы знать, может ли CREATE TABLE
и аналогичный DDL вернуться в
- Postgres
- MySQL
- SQLite
- и др.
Опишите, как каждая база данных обрабатывает транзакции с помощью DDL.
Я работаю над программой, которая выдает DDL. Я хотел бы знать, может ли CREATE TABLE
и аналогичный DDL вернуться в
Опишите, как каждая база данных обрабатывает транзакции с помощью DDL.
http://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis дает обзор этой проблемы с точки зрения PostgreSQL.
Является ли транзакция DDL в соответствии с этим документом?
SQLite также, похоже, имеет DDL транзакции. Я смог выполнить ROLLBACK
a CREATE TABLE
в SQLite. В документации CREATE TABLE
не упоминаются специальные транзакционные "gotchas".
PostgreSQL имеет транзакционный DDL для большинства объектов базы данных (конечно, таблицы, индексы и т.д., но не базы данных, пользователи). Однако практически любой DDL получит блокировку ACCESS EXCLUSIVE
на целевом объекте, делая его полностью недоступным, пока транзакция DDL не завершится. Кроме того, не все ситуации обрабатываются, например, если вы попытаетесь выбрать из таблицы foo
, в то время как другая транзакция отбрасывает ее и создает таблицу замены foo
, тогда заблокированная транзакция, наконец, получит ошибку, а не обнаружит новый стол foo
. (Изменить: это было исправлено в или перед PostgreSQL 9.3)
CREATE INDEX ... CONCURRENTLY
является исключительным, он использует три транзакции для добавления индекса в таблицу, разрешая одновременные обновления, поэтому сам он не может быть выполнен в транзакции.
Также команда обслуживания базы данных VACUUM
не может использоваться в транзакции.
Хотя это не означает "откат", в Oracle команда FLASHBACK может использоваться для отмены этих типов изменений, если база данных настроена для ее поддержки.
Это не может быть сделано с MySQL, кажется, очень глупо, но верно... (согласно принятому ответу)
"Оператор CREATE TABLE в InnoDB обрабатывается как отдельная транзакция. Это означает, что ROLLBACK от пользователя не отменяет операторы CREATE TABLE, сделанные пользователем во время этой транзакции".
https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html
Пробовал несколько разных способов, и он просто не откатится..
Обходной путь - просто установить флаг ошибки и выполнить команду "drop table tblname" в случае сбоя одного из запросов.
Просто, чтобы дополнить эту нить, H2 также не поддерживает транзакционные DDL заявления для большинства команд SQL, в соответствии с этим.
Похоже, другие ответы довольно устарели.
По состоянию на 2019 год: