我们先看一个具体的例子
会话1,创建一个简单表,并在上面创建一个存储过程:
- 11gR1 Piner>create table test (a int);
- Table created.
- 11gR1 Piner>create or replace procedure sp_test
- 2 as
- 3 num number;
- 4 begin
- 5 select count(*) into num from test;
- 6 end;
- 7 /
- 11gR1 Piner>select object_name,status from user_objects where object_name='SP_TEST';
- OBJECT_NAME STATUS
- ------------------------------ -------
- SP_TEST VALID
同样的会话,我们插入一条记录,查看锁状态:
- 11gR1 Piner>insert into test values(1);
- 1 row created.
- 11gR1 Piner>SELECT USERENV('SID') FROM DUAL;
- USERENV('SID')
- --------------
- 118
- 11gR1 Piner>select sid,id1,id2,type,lmode,request from v$lock
- 2 where sid = 118;
- SID ID1 ID2 TY LMODE REQUEST
- ---------- ---------- ---------- -- ---------- ----------
- 118 99 0 AE 4 0
- 118 71091 0 TM 3 0
- 118 524292 679 TX 6 0
可以看到,这里对比以前的版本,多了一个类型为AE的锁。
然后,我们在另外一个会话做另外的操作
会话2:增加列
- SQL> alter table test add b int;
- Table altered.
- SQL> alter table test drop column b;
- alter table test drop column b
- *
- ERROR at line 1:
- ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
- 11gR1 Piner>select object_name,status from user_objects where object_name='SP_TEST';
- OBJECT_NAME STATUS
- ------------------------------ -------
- SP_TEST VALID
可以看到,列增加成功,并没有任何阻塞,但是,drop列是阻塞的。是因为add新列并不影响正在执行的dml,但是drop老列却是可能影响到正在执行的DML的。
也可以看到,增加列的过程完成以后,存储过程并不失效。这个是很好的一个特性,只要不让存储过程错误,就不会使得存储过程INVALID,减少了DDL引发的library cache pin可能导致的系统异常。
我们另外看看oracle 11g的一个ddl timeout参数,在会话2上修改此参数,并重新执行刚才的drop列的命令。
- SQL> show parameter ddl_lock_timeout;
- NAME_COL_PLUS_SHOW_PARAM TYPE VALUE_COL_PLUS_SHOW_PARAM
- ------------------------------ ----------- --------------------------
- ddl_lock_timeout integer 0
- SQL> alter system set ddl_lock_timeout = 10;
- System altered.
- SQL> set timing on
- SQL> alter table test drop column b;
- alter table test drop column b
- *
- ERROR at line 1:
- ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
- Elapsed: 00:00:10.00
这里的ddl_lock_timeout表示ddl会等待设置的值(单位为秒),这个是很有用的,比如在一个更新很频繁的表上面,适当的等待可以让ddl执行成功,以前dcba专门写了一个循环来模拟这个等待,现在,终于有这个参数了。
可以看到,正好等待10s左右
现在,会话1,我们提交该事务
- 11gR1 Piner>commit;
- Commit complete.
会话2,drop终于可以成功了
- SQL> alter table test drop column b;
- Table altered.
我们再查看存储过程的状态
- 11gR1 Piner>select object_name,status from user_objects where object_name='SP_TEST';
- OBJECT_NAME STATUS
- ------------------------------ -------
- SP_TEST VALID
整个简单测试到此完成,大家看到了几处跟以前10g不一样的地方?可以看到的是,oracle在一些细节的地方,处理的越来越好了。
上一篇: « 停水36小时
下一篇: 杂事·琐事·平常事·烦心事 »
- 发表评论


