我正在开发一个能够发出DDL(数据定义语言)的程序。我想了解在以下数据库中,
CREATE TABLE
和其他相似的DDL操作是否可以回滚。
- Postgres
- MySQL
- SQLite
- 等等
CREATE TABLE
和其他相似的DDL操作是否可以回滚。
http://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis提供了PostgreSQL的观点关于此问题的概述。
根据该文档,DDL是否是事务性的?
SQLite似乎也具有事务性的DDL。 我能够在SQLite中使用ROLLBACK
回滚CREATE TABLE
语句。其CREATE TABLE
文档未提及任何特殊的事务性问题。
PostgreSQL为大多数数据库对象提供了事务性DDL(如表、索引等),但不支持对数据库和用户进行DDL操作。然而,实际上任何DDL都会在目标对象上获取ACCESS EXCLUSIVE
锁,使其在DDL事务完成之前完全无法访问。此外,并非所有情况都能得到很好处理——例如,如果您尝试从表foo
中选择数据,同时另一个事务正在删除它并创建一个替换表foo
,则被阻塞的事务最终将收到错误消息而不是找到新的foo
表。(编辑:这个问题在 PostgreSQL 9.3或之前版本中已经得到解决)
CREATE INDEX ... CONCURRENTLY
是一个例外,它使用三个事务向表添加索引,同时允许并发更新,因此不能在一个事务中执行。
此外,数据库维护命令 VACUUM
不能在事务中使用。
foo
时尝试从中选择,那么我可以接受旧版本或错误。我不接受新版本,因为它还没有提交,所以我不能看到它。我可以接受错误,因为在并发事务访问中,必须准备好重新启动事务。如果错误比必要的更频繁地发生,可能会降低性能,但仍然是正确的。 - Jan Hudechttps://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html
尝试了几种不同的方法,但它仍然无法回滚.. 解决方法是简单地设置一个失败标志并执行"drop table tblname",如果其中一个查询失败..看起来其他答案都比较过时。
截至2019年:
虽然严格来说它不是“回滚”,但在Oracle中,如果数据库已配置支持,则可以使用FLASHBACK命令撤消这些类型的更改。