114

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

  • Postgres
  • MySQL
  • SQLite
  • 等人

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

4

5 回答 5

160

http://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis从 PostgreSQL 的角度概述了这个问题。

根据本文档,DDL 是事务性的吗?

  • PostgreSQL - 是的
  • MySQL - 不;DDL 导致隐式提交
  • Oracle Database 11g 第 2 版及更高版本 - 默认情况下不支持,但存在称为基于版本的重新定义的替代方法
  • 旧版本的 Oracle - 否;DDL 导致隐式提交
  • SQL Server - 是的
  • Sybase Adaptive Server - 是
  • DB2 - 是的
  • Informix - 是的
  • Firebird (Interbase) - 是的

SQLite 似乎也有事务性 DDL。我能够ROLLBACKCREATE TABLESQLite 中声明。它的CREATE TABLE文档没有提到任何特殊的交易“陷阱”。

于 2011-01-19T14:26:42.057 回答
32

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

CREATE INDEX ... CONCURRENTLY是例外,它使用三个事务向表添加索引,同时允许并发更新,因此它本身不能在事务中执行。

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

于 2011-01-14T16:07:11.413 回答
8

似乎无法用MySQL完成,非常愚蠢,但确实如此......(根据接受的答案)

“InnoDB 中的 CREATE TABLE 语句作为单个事务处理。这意味着来自用户的 ROLLBACK 不会撤消用户在该事务期间所做的 CREATE TABLE 语句。”

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

尝试了几种不同的方法,它根本不会回滚..

解决方法是简单地设置一个失败标志并在其中一个查询失败时执行“drop table tblname”。

于 2017-11-14T21:35:24.127 回答
4

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

于 2011-01-14T15:50:53.023 回答
4

看起来其他答案已经过时了。

截至 2019 年:

  • Postgres 在许多版本中都支持事务 DDL。
  • SQLite 在许多版本中都支持事务 DDL。
  • MySQL从 8.0(2018 年发布)开始支持 Atomic DDL。
于 2019-06-24T14:02:18.167 回答