Chinaunix首页 | 论坛 | 博客
  • 博客访问: 606070
  • 博文数量: 796
  • 博客积分: 5000
  • 博客等级: 大校
  • 技术积分: 5095
  • 用 户 组: 普通用户
  • 注册时间: 2008-09-10 09:43
文章分类

全部博文(796)

文章存档

2011年(1)

2008年(795)

我的朋友

分类:

2008-09-10 09:59:15

  当我们发出DDL命令时,会自动在被处理的对象上添加DDL锁定,从而防止对象被其他用户所修改。当DDL命令结束以后,则释放DDL锁定。我们不能显式地请求一个DDL锁定,只有当对象结构被修改或者被引用时,才会在对象上添加DDL锁定。比如创建或者编译过程时会对引用的对象添加DDL锁定。在创建视图时,也会对引用的表添加DDL锁定等。

  在执行DDL命令之前,会自动添加一个隐式提交命令,然后执行具体的DDL命令,在DDL命令执行结束之后,还会自动添加一个隐式提交命令。实际上,在执行DDL命令时,都会将其转换为对数据字典表的DML操作。比如我们发出创建表的DDL命令时,Oracle会将表的名称插入数据字典表tab$里,同时将表里的列名以及列的类型插入col$表里等。因此,在DDL命令中需要添加隐式的提交命令,从而提交那些对数据字典表的DML操作。即使DDL命令失败,它也会发出提交命令。

  我们来看下面的例子,启动两个session,其中一个叫做sess #1,另一个叫做sess #2。在sess #1里发出如下的SQL语句:

      SQL> insert into t values(1);
  1 row created.

  然后在sess #2里查询表T里的数据:

      SQL> select * from t;
  no rows selected

  显然,由于sess #1还没有提交,因此sess #2里不能检索出sess #1所插入的记录。接下来,我们在sess #1里执行下面的语句:

      SQL> create table t(c1 number);
  create table t(c1 number)
  *
  ERROR at line 1:
  ORA-00955: name is already used by an existing object

  由于表T已经存在,因此创建表T的命令失败。这时我们再回到sess #2里查询表T:

      SQL> select * from t;
  ID
  ----------
  1

  很明显,我们并没有在sess #1里发出commit命令,但这时sess #1里所作的插入操作已经被提交了。这个commit就是通过create table这个DDL命令隐式发出的,尽管create table命令已经失败了。

  DDL锁定具有以下三种类型。

  ž 排他的DDL锁定(Exclusive DDL Lock)

  大部分的DDL操作都会在被操作的对象上添加排他的DDL锁定,从而防止在DDL命令执行期间,对象被其他用户所修改。当对象上添加了排他的DDL锁定以后,该对象上不能再添加任何其他的DDL锁定。如果是对表进行DDL命令,则其他进程也不能修改表里的数据。

  ž 共享的DDL锁定(Shared DDL Lock)

  用来保护被DDL的对象不被其他用户进程所更新,但是允许其他进程在对象上添加共享的DDL锁定。如果是对表进行DDL命令,则其他进程可以同时修改表里的数据。比如我们发出create view命令创建视图时,在视图的所引用的表(这种表也叫基表)上添加的就是共享的DDL命令。也就是说,在创建视图时,其他用户不能修改基表的结构,但是可以更新基表里的数据。

[1]  

【责编:Chuan】

--------------------next---------------------

阅读(338) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~