最近,我发现MySQL 不支持DDL的回滚,例如“ alter table”。习惯于PostgreSQL,这让我感到奇怪,但是我的一个朋友告诉我,即使Oracle也不允许。有不支持它的技术原因吗?对于他们来说,这仅仅是一个“无趣的”功能吗?
编辑:刚刚发现此比较。它看起来像有很多的DBMS是做支持事务DDL。
DROP
或a RENAME
吗?
最近,我发现MySQL 不支持DDL的回滚,例如“ alter table”。习惯于PostgreSQL,这让我感到奇怪,但是我的一个朋友告诉我,即使Oracle也不允许。有不支持它的技术原因吗?对于他们来说,这仅仅是一个“无趣的”功能吗?
编辑:刚刚发现此比较。它看起来像有很多的DBMS是做支持事务DDL。
DROP
或a RENAME
吗?
Answers:
之所以在PostgreSQL中起作用,是因为系统目录是常规表。因此,例如,创建一个新函数只需要在pg_proc
表中插入一行,更改列的默认值,只需要对中的某行进行更新pg_attrdef
,依此类推。由于表无论如何都是事务性的,因此您几乎必须全力以赴,以使其无法正常工作。(这里省略了许多痛苦的实现细节。;-))
我想,不知道源代码,其他数据库引擎使用一些自定义内部结构来表示其系统目录信息。因此,他们必须付出额外的努力,可能还要付出很多额外的努力,才能使事务性DDL正常工作,这显然不是他们的优先考虑。
不利的一面是,这就是PostgreSQL主要版本升级如此痛苦的原因。其他产品大概可以在设计内部元数据结构时考虑到更改和更新,因此升级到新的主要版本没有问题。在PostgreSQL中,无法将系统目录表更改为突然看起来像系统目录表的较新版本,至少在使系统保持在线状态时至少不会如此,因为这将需要访问系统目录。嗯
最不?笨蛋
我主要使用SQL Server,但确实如此。我知道Oracle没有,但是我认为Oracle可能是一种畸变。
在SQL Server中,我可以肯定您可以在一个事务中运行多个DDL语句,尽管我也认为有两个限制(我都忘记了)。您可以根据需要对大多数事物进行创建,更改或删除,然后将其回滚。Red-Gate SQL Compare(我喜欢的工具)利用了这一优势。
这样做的问题是您的事务范围变得相当有趣...当您将系统目录包含在更新事务(DDL)中时,您将冒获得一些非常重要的锁的风险,并且可能会阻止对系统目录的访问。如果他们的查询在目录中找不到他们的表,用户将无法做很多事情!
总而言之,能够将DDL包含在多语句事务中很方便。
更有用的是,SQL Server DDL命令TRUNCATE
也可以是多语句事务的元素。您可以截断目标表(非常快),构建它,然后根据需要执行提交。如果出现问题,请回滚并瞧瞧,就像您从未打扰过桌子一样。日志空间也最小化。我经常利用这一点。
TRUNCATE
无法回滚。我错了。
在SQL Server中,我们可以回滚DDL语句,它不在语句末尾使用自动提交。在其他DBMS中,我不知道,但我记得在Oracle中不能做到这一点。我相信它是特定于每个DBMS的,不确定SQL标准对此会说些什么,但是我确定没有生产者会实施100%的标准。
SO上存在类似的问题:是否可以在事务中(在SQL Server中)运行多个DDL语句?
Oracle具有共享的查询解析功能,因此一个会话执行的SELECT * FROM table_a(通常)与另一会话相同。如果一个会话认为表中有十列,而另一会话认为有十一列,那将被打破。