【问题标题】:Why execution of this block never ends?为什么这个块的执行永远不会结束?
【发布时间】:2015-03-17 05:48:30
【问题描述】:

假设我们有一个包 PACK

package PACK is procedure DO; end PACK;

package body PACK is       
        procedure DO is begin DBMS_OUTPUT.PUT_LINE('Hello from PACK'); end;
end PACK;

为什么会执行块

begin
    PACK.do;
    execute immediate 'alter package PACK compile';
end;

永远不会结束(会话似乎挂起)?但是,分别执行第一行和第二行(在不同的匿名块中)是成功的。

【问题讨论】:

    标签: oracle plsql oracle11g


    【解决方案1】:

    该包已被使用,这意味着它的instance 仍处于活动状态。所以,除非它被杀死,否则你不能改变它的状态。

    当调用过程或任何存储函数时,该会话会在该对象状态上获取锁定。除非调用者完成模块,否则锁将保持活动状态。

    在您的情况下,您正试图在调用它的同一个 PL/SQL 块中更改包。结果为deadlockPL/SQL 块试图动态执行你的 DDL,但是当第一次调用包时,锁已经到位!

    请注意,相同的 PL/SQL 在此之后仍然可以调用该包 动态 DDL(也可以是 DROP!)。所以为了一致性起见,锁 除非整个 PL/SQL 完成,否则不会发布!

    ORA-04021: timeout occurred while waiting to lock object ..
    

    当你调用 separate PL/SQL 块时,锁已经被释放了。在调用 DDL 之前。

    尝试在不同的会话中运行此 SQL。

    select * from v$access where object = 'PACK';
    

    【讨论】:

      猜你喜欢
      • 2013-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-04
      • 2015-08-28
      • 2016-08-04
      • 2020-09-11
      • 2015-01-18
      相关资源
      最近更新 更多