【发布时间】:2011-06-09 05:25:27
【问题描述】:
我正在开发一个发布 DDL 的程序。我想知道CREATE TABLE和类似的DDL是否可以回滚
- Postgres
- MySQL
- SQLite
- 等
描述每个数据库如何使用 DDL 处理事务。
【问题讨论】:
标签: sql transactions ddl create-table
我正在开发一个发布 DDL 的程序。我想知道CREATE TABLE和类似的DDL是否可以回滚
描述每个数据库如何使用 DDL 处理事务。
【问题讨论】:
标签: sql transactions ddl create-table
看起来其他答案已经过时了。
截至 2019 年:
【讨论】:
START TRANSACTION ... COMMIT;。因此,如果同一事务中的后一个语句失败,您仍然无法回滚事务中的 DDL 语句。(见注释在dev.mysql.com/doc/refman/8.0/en/…)
不能用 MySQL 完成,看起来很愚蠢,但确实如此......(根据公认的答案)
"InnoDB 中的 CREATE TABLE 语句作为单个处理 交易。这意味着来自用户的 ROLLBACK 不会撤消 用户在该事务期间所做的 CREATE TABLE 语句。”
https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html
尝试了几种不同的方法,它根本不会回滚..
解决方法是简单地设置一个失败标志并在其中一个查询失败时执行“drop table tblname”..
【讨论】:
http://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis 从 PostgreSQL 的角度概述了这个问题。
根据本文档,DDL 是事务性的吗?
SQLite 似乎也有事务性 DDL。我能够在 SQLite 中 ROLLBACK CREATE TABLE 声明。它的CREATE TABLE 文档没有提到任何特殊的事务性“陷阱”。
【讨论】:
ALTER TABLE 语句也可以回滚。 documentation 中没有明确提及。这里提到的是如何在事务中执行“高级”更改。
PostgreSQL 为大多数数据库对象(当然是表、索引等,但不包括数据库、用户)提供事务 DDL。然而,实际上任何 DDL 都会在目标对象上获得ACCESS EXCLUSIVE 锁定,使其在 DDL 事务完成之前完全无法访问。此外,并非所有情况都得到了很好的处理——例如,如果您尝试从表 foo 中进行选择,而另一个事务正在删除它并创建替换表 foo,那么被阻止的事务最终将收到一个错误,而不是找到新的foo 表。 (编辑:这是在 PostgreSQL 9.3 或之前修复的)
CREATE INDEX ... CONCURRENTLY 是个例外,它使用三个事务向表添加索引同时允许并发更新,因此它本身不能在事务中执行。
另外,数据库维护命令VACUUM不能在事务中使用。
【讨论】:
foo 中进行选择,而另一个事务正在删除并重新创建它,那么我可以接受旧版本或错误。我对新版本不满意,因为它还没有提交,所以我一定看不到它。我可以接受错误,因为在并发事务访问中,无论如何都必须准备好重新启动事务。如果错误发生的频率超出了必要,它可能会降低性能,但它仍然是正确的。
虽然严格来说它不是“回滚”,但在 Oracle 中,FLASHBACK 命令可用于撤消这些类型的更改,前提是数据库已配置为支持它。
【讨论】: