oracle - 为什么这个 block 的执行永远不会结束?

标签 oracle plsql oracle11g

假设我们有一个包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;

为什么执行 block

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

永远不会结束( session 似乎挂起)?但是,第一行和第二行(在不同的匿名 block 中)的单独执行是成功的。

最佳答案

该包已被使用,这意味着它的一个实例仍然是活跃的。所以,除非它被杀死,否则你不能改变它的状态。

当一个过程或任何存储函数被调用时,该 session 会在该对象状态上获取一个锁。除非调用者完成模块,否则锁将保持事件状态。

在您的例子中,您试图在调用它的同一个 PL/SQL block 中更改包。它导致死锁PL/SQL block 试图动态执行您的 DDL,但在首次调用程序包时已经锁定!

Please note that same PL/SQL can still call the package after this dynamic DDL (It can be DROP too!). So for consistency sake, the lock is not released unless the entire PL/SQL is been completed!

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

当您调用一个单独的 PL/SQL block 时,锁已经被释放了。在调用 DDL 之前。

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

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

关于oracle - 为什么这个 block 的执行永远不会结束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29092125/

相关文章:

database - Oracle 数据库多实例配置

sql - Oracle 中相当于 SQL Server 的 SET NOCOUNT ON 的是什么?

sql - 如何查看当前Oracle DBMS是否是企业版?

oracle - 存储过程异常处理

sql - Oracle sql中使用countif计算每一行

java - ORA-06553 Oracle 中带有 Blob 的 java 函数参数错误

java - Java Servlet 和数据库连接错误

java - 组织.hibernate.MappingException : No Dialect mapping for JDBC type: 2002

c# - 这是错误 ORA-12154 : TNS:could not resolve the connect identifier specified?

oracle - 在 Oracle 中从 varchar 查找下一个 id