下面我们用一个例子,来验证一下Library cache lock/pin。 例10:观察Library cache lock/pin 的状态: 先建立一下如下过程: create or replace procedure jj_cur is cursor aa is select kglhdlmd,kglhdpmd from x$kglob where kglnaobj='select * from aa_1 where id=1' and kglhdadr<>kglhdpar;
kk number:=5;
kk1 number:=5;
begin
for i in 1..2000 loop
kk:=5;
kk1:=5;
open aa;
fetch aa into kk,kk1;
dbms_output.put_line(kk||'-'||kk1);
close aa;
end loop;
end; / Kglhdadr是游标句柄,而Kglhdpar是父游标句柄,条件中的kglhdadr<>kglhdpar ,目的是只显示子游标。Kglhdlmd是Library cache lock的模式,为0时表示没有锁,1是NULL锁,2是共享锁,3是独占锁。Kglhdpmd是Library cache pin的模式,0是没有Pin,2是共享Pin,3是独占Pin。 另外,我们作为测试用的SQL声明select * from aa_1 where id=1,要保证只有一个子游标,这样做的目的,就是让过程中的游标AA只选出来一条记录。在过程执行完毕后,最好再执行声明:select kglhdlmd,kglhdpmd from x$kglob where kglnaobj='select * from aa_1 where id=1' and kglhdadr<>kglhdpar一次,看一下能选出来几行,如果多于一行,说明声明子游标的数量多于一条,应该换一条声明再试。 在会话A中: spool e:\oracle\aaa.txt exec jj_cur; 在会话B中: select * from aa_1 where id=1; 在会话A中: spool off 查看e:\oracle\aaa.txt,可以看到,在会话B的声明执行时:Library cache lock先是1,然后是0。而Library cache pin先是3,后是2,然后是0。会话B中的声明是第一次执行,这是硬解析,所以会有很短时间的独占Pin。上面的例子,可以再试一次,这次,就是软解析了。试验过程同上,结果是,Library cache lock仍是1,然后是0,而Library cache pin则是2,然后是0,不再有3了。 我们可以再用上面的方法,测试一下父游标上的锁的情况,这里就略过了。 我记得有资料上说,声明在解析时,在父、子游标上会有独占锁的,但是在上面的测试中,却没有看到。有可能是我的过程执行速度不过快,无法捕找到句柄上的独占锁。 library.GIF (17.71 KB) 2008-3-8 00:28