是否可以回滚主要 SQL 数据库中的 CREATETABLE 和 ALTERTABLE 语句?

我正在研究一个发行 DDL 的程序。我想知道是否 CREATE TABLE和类似的 DDL 可以回滚

  • 邮差
  • MySQL
  • SQLite
  • 等等

描述每个数据库如何使用 DDL 处理事务。

92175 次浏览

虽然严格来说它不是“回滚”,但是在 Oracle 中,如果数据库已经配置为支持 FLASHBACK,那么可以使用 FLASHBACK 命令来撤消这些类型的更改。

PostgreSQL 为大多数数据库对象(当然是表、索引等,但不包括数据库和用户)提供事务性 DDL。然而,实际上任何 DDL 都会在目标对象上获得 ACCESS EXCLUSIVE锁,使其在 DDL 事务完成之前完全无法访问。此外,并非所有情况都能得到很好的处理——例如,如果您试图从表 foo中进行选择,而另一个事务正在删除它并创建一个替换表 foo,那么被阻塞的事务最终将收到一个错误,而不是找到新的 foo表。(编辑: 这是在 PostgreSQL 9.3中或之前修复的)

CREATE INDEX ... CONCURRENTLY is exceptional, it uses three transactions to add an index to a table while allowing concurrent updates, so it cannot itself be performed in a transaction.

此外,数据库维护命令 VACUUM也不能在事务中使用。

Http://wiki.PostgreSQL.org/wiki/transactional_ddl_in_postgresql:_a_competitive_analysis 从 PostgreSQL 的角度概述了这个问题。

根据这个文档 DDL 是事务性的吗?

  • PostgreSQL-是的
  • MySQL-no; DDL 导致隐式提交
  • Oracle Database 11g Release2及以上版本——默认情况下,没有,但存在一种称为基于版本的重新定义的替代方案
  • 旧版本的 Oracle-no; DDL 导致隐式提交
  • SQL Server-是的
  • Sybase AdaptiveServer-是的
  • DB2 - yes
  • Informix-是的
  • 火鸟(中间基地)-是的

SQLite 似乎也具有事务性 DDL。我能够在 SQLite 中使用 ROLLBACK作为 CREATE TABLE语句。它的 CREATE TABLE文档没有提到任何特殊的事务性“陷阱”。

MySQL似乎做不到,非常愚蠢,但是真的... (根据接受的答案)

”InnoDB 中的 CREATETABLE 语句作为单个 这意味着来自用户的 ROLLBack 不会撤消 用户在该事务中创建的 CREATETABLE 语句。”

Https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html

Tried a few different ways and it simply won't roll back..

解决方法是简单地设置一个失败标志,如果其中一个查询失败,则执行“删除 table tblname”。

看来其他答案都过时了。

截至2019年:

  • Postgres 在许多版本中都支持事务性 DDL。
  • SQLite 在许多版本中都支持事务性 DDL。
  • MySQL 支持 Atomic DDL since 8.0(2018年发布)。