博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
oracle中ddl为什么不能回滚
阅读量:5873 次
发布时间:2019-06-19

本文共 1724 字,大约阅读时间需要 5 分钟。

hot3.png

在ITPUB上看到有人提出了这个问题。在Sqlserver或一些其他的数据库中,DDL语句也是可以回滚的,那么Oracle为什么不能回滚DDL语句呢。

这个问题来自:

 

 

要说明这个问题,首先需要说明什么是DDL语句。DDL语句是数据定义语句,包括各种数据对象的创建、修改和删除,以及授权等操作。

在Oracle中DDL语句将转化为修改数据字典表的DML语句。一个简单的修改表的DDL语句,会导致Oracle在后台通过递归SQL语句进行大量的查询和修改的操作。

如果有兴趣,可以通过SQL_TRACE根据一下DDL语句,检查一下Oracle后台实际执行了哪些操作。

在Oracle中,Oracle执行DDL前会发出一个COMMIT语句,然后执行DDL操作,最后再发出一个COMMIT操作。

前面提到了对于Oracle而言,DDL实际上是数据字典表的一系列的修改,也就是数据字典表的DML操作,那么理论上讲Oracle是完全有能力实现DDL语句的回滚的,那么Oracle为什么设计成现在的工作方式。要知道Oracle以灵活和强大的可定制性著称,但是Oracle没有给用户任何回滚DDL的可能性,显示是存在着十分充分的理由。

首先分析一下Oracle为什么要在DDL语句之前和之后各执行一次COMMIT,其实道理很简单,Oracle是为了将用户的读写操作和数据字典的修改隔离开,用户数据的读写不应该和数据字典的操作放在同一个事务中。

为了说明Oracle为什么不回滚DDL语句,下面假设Oracle可以回滚DDL语句,看看这会给Oracle数据库带来什么影响。

从现在开始,假设DDL并不会自动提交,而是事务中的一部分。

那么DDL就要满足READ COMMIT隔离机制,也就是说,用户执行的DDL语句在提交前,其他用户是无法看到的。比如A用户执行CREATE TABLE T的语句,然后对T执行了一些DML。而这时其他会话是无法看到T表的。

那么考虑这样的情况,存在表T,包含两个列,一个ID列,一个CREATED列。

A会话执行了ALTER TABLE T MODIFY CREATED DEFAULT SYSDATE NOT NULL,然后对T表进行了一些插入,但是没有提交。

这时B会话尝试插入T表,如果DDL语句不是事务的一部分,那么B的插入和A会话的插入之间没有冲突,但是现在情况不同,由于A执行了T表的修改,为CREATED列增加了默认值并设置为NOT NULL,而且这个修改B会话当前是看不到的,因为A并没有提交修改。这时如果B会话的插入没有提供CREATED列的值,则插入操作将被锁定。对于B而言,表结构中CREATED列仍然是可空的,因此允许插入CREATED列为空的记录,但是由于A已经设置T的CREATED列非空,且包含默认值,因此B的插入必须被锁定,否则如果A和B全部提交,A会话会发现即使执行了DDL语句,T表中仍然存在CREATED为空的记录。Oracle为了实现DDL可以回滚的功能,且实现多版本读一致性,那么就必须在DDL发生后,将修改的表锁定,避免其他会话的访问造成不一致。这会导致Oracle中出现锁升级的情况,并且严重的影响Oracle的并发性,而且会大大增加死锁产生的几率。

也许有人奇怪SQLSERVER或一些其他的数据库为什么可以实现DDL语句的回滚。事实上,前面提到了Oracle也是有能力实现DDL回滚的,只是这会极大的影响Oracle的并发性。要知道,Oracle的锁机制和多版本读一致性使得Oracle的并发性在所有数据库产品中首屈一指。显然为了实现DDL的回滚而损失最值得称道的并发性,Oracle认为得不偿失。其他数据库之所以可以实现,是因为这些数据库的锁机制本身就存在一定缺陷,比如大量的锁会占用系统的资源、读写操作互相阻塞、行级锁可能自动升级为表级锁。由于已经存在这些问题,所以实现DDL的回滚并不会在很大程度上使得并发性恶化,因为即使DDL不将行锁升级为表锁,可能其他的因素也会导致这种情况的发生。

转载于:https://my.oschina.net/u/556364/blog/78877

你可能感兴趣的文章
七天学会ASP.NET MVC (四)——用户授权认证问题
查看>>
upgrade to iOS7,how to remove stroyboard?
查看>>
影响企业信息化成败的几点因素
查看>>
SCCM 2016 配置管理系列(Part8)
查看>>
zabbix监控部署
查看>>
struts中的xwork源码下载地址
查看>>
Android硬件抽象层(HAL)深入剖析(二)
查看>>
CDays–4 习题一至四及相关内容解析。
查看>>
L3.十一.匿名函数和map方法
查看>>
java面向对象高级分层实例_实体类
查看>>
android aapt 用法 -- ApkReader
查看>>
[翻译]用 Puppet 搭建易管理的服务器基础架构(3)
查看>>
Android -- AudioPlayer
查看>>
Python大数据依赖包安装
查看>>
Android View.onMeasure方法的理解
查看>>
Node.js 爬虫初探
查看>>
ABP理论学习之仓储
查看>>
centos7下使用yum安装mysql
查看>>
How can I set ccshared=-fPIC while executing ./configure?
查看>>
2.移植uboot-添加2440单板,并实现NOR、NAND启动
查看>>