Я работаю над программой, которая выдает 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
с CREATE TABLE
заявлением в SQLite. В его CREATE TABLE
документации не упоминаются какие-либо особые транзакционные "подводные камни".
ALTER TABLE
оператор SQLite также можно откатить. Это не упоминается явно в документации . Там упоминается, как выполнять «расширенные» изменения внутри транзакции.
PostgreSQL имеет транзакционный DDL для большинства объектов баз данных (конечно, таблиц, индексов и т. Д., Но не баз данных, пользователей). Однако практически любой DDL получит ACCESS EXCLUSIVE
блокировку целевого объекта, что сделает его полностью недоступным до завершения транзакции DDL. Кроме того, не все ситуации полностью обрабатываются - например, если вы попытаетесь выбрать из таблицы, в foo
то время как другая транзакция отбрасывает ее и создает таблицу замены foo
, тогда заблокированная транзакция, наконец, получит ошибку, а не найдет новую foo
таблицу. (Изменить: это было исправлено в PostgreSQL 9.3 или ранее)
CREATE INDEX ... CONCURRENTLY
является исключительным, он использует три транзакции для добавления индекса в таблицу, позволяя одновременные обновления, поэтому сам по себе он не может быть выполнен в транзакции.
Также VACUUM
в транзакции нельзя использовать команду обслуживания базы данных .
foo
пока другая транзакция отбрасывает и воссоздает ее, то у меня все в порядке со старой версией или ошибкой. Меня не устраивает новая версия, потому что она еще не зафиксирована, поэтому я не должен ее видеть. Я в порядке с ошибкой, потому что при одновременном доступе к транзакциям нужно быть готовым к перезапуску транзакций в любом случае. Если ошибки случаются чаще, чем необходимо, это может снизить производительность, но это все равно верно.
Хотя, строго говоря, это не «откат», в Oracle команду FLASHBACK можно использовать для отмены этих типов изменений, если база данных была настроена для ее поддержки.
Похоже, другие ответы устарели.
По состоянию на 2019 год:
START TRANSACTION ... COMMIT;
вы по-прежнему не можете откатить операторы DDL в транзакции, если последний в той же транзакции не работает. (См. Примечание в разделе dev. mysql.com/doc/refman/8.0/en/... )
Невозможно сделать с MySQL, кажется, очень глупо, но это правда ... (согласно принятому ответу)
«Оператор CREATE TABLE в InnoDB обрабатывается как единая транзакция. Это означает, что ROLLBACK от пользователя не отменяет операторы CREATE TABLE, сделанные пользователем во время этой транзакции».
https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html
Пробовал несколько разных способов и просто не откатывается ..
Чтобы решить эту проблему, просто установите флаг ошибки и выполните команду «drop table tblname», если один из запросов завершился неудачно.