繁体   English   中英

是否可以在主要 SQL 数据库中回滚 CREATE TABLE 和 ALTER TABLE 语句?

[英]Is it possible to roll back CREATE TABLE and ALTER TABLE statements in major SQL databases?

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

  • Postgres
  • MySQL
  • SQLite

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

截至 2019 年:

  • Postgres 已支持许多版本的事务性 DDL。
  • SQLite 已支持许多版本的事务性 DDL。
  • MySQL从 8.0 (2018 年发布)开始支持Atomic DDL

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM