我正在研究一个发行 DDL 的程序。我想知道是否 CREATE TABLE和类似的 DDL 可以回滚
CREATE TABLE
描述每个数据库如何使用 DDL 处理事务。
虽然严格来说它不是“回滚”,但是在 Oracle 中,如果数据库已经配置为支持 FLASHBACK,那么可以使用 FLASHBACK 命令来撤消这些类型的更改。
PostgreSQL 为大多数数据库对象(当然是表、索引等,但不包括数据库和用户)提供事务性 DDL。然而,实际上任何 DDL 都会在目标对象上获得 ACCESS EXCLUSIVE锁,使其在 DDL 事务完成之前完全无法访问。此外,并非所有情况都能得到很好的处理——例如,如果您试图从表 foo中进行选择,而另一个事务正在删除它并创建一个替换表 foo,那么被阻塞的事务最终将收到一个错误,而不是找到新的 foo表。(编辑: 这是在 PostgreSQL 9.3中或之前修复的)
ACCESS EXCLUSIVE
foo
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.
CREATE INDEX ... CONCURRENTLY
此外,数据库维护命令 VACUUM也不能在事务中使用。
VACUUM
Http://wiki.PostgreSQL.org/wiki/transactional_ddl_in_postgresql:_a_competitive_analysis 从 PostgreSQL 的角度概述了这个问题。
根据这个文档 DDL 是事务性的吗?
SQLite 似乎也具有事务性 DDL。我能够在 SQLite 中使用 ROLLBACK作为 CREATE TABLE语句。它的 CREATE TABLE文档没有提到任何特殊的事务性“陷阱”。
ROLLBACK
用 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年: