ORA-04061: 包体“PACKAGE.NAME”的现有状态已失效,但仍然存在

2024-05-21

在我正在处理的一个 Oracle 数据库实例上,我在重新编译包时观察到与正常行为不同的行为。

通常,(如所讨论的Oracle 中频繁出现错误 ORA-04068: 包的现有状态已被丢弃 https://stackoverflow.com/questions/1761595/frequent-error-in-oracle-ora-04068-existing-state-of-packages-has-been-discarde)PL/SQL 包重新编译后,首次调用时预计会出现以下错误:

ERROR at line 1:
ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package body "PACKAGE.NAME" has been
invalidated
ORA-06508: PL/SQL: could not find program unit being called:
"PACKAGE.NAME"
ORA-06512: at line 1

但第二次调用应该可以正常工作,当然前提是包没有错误。此行为以前曾在该环境中出现过。同时我们从11g R2升级到12c R1,并启用了基于版本的重新定义。

现在我遇到的问题是我一直得到:

ORA-04061: existing state of package body "PACKAGE.NAME" has been
invalidated
ORA-06508: PL/SQL: could not find program unit being called:
"PACKAGE.NAME"
ORA-06512: at line 1

因此,不再出现 ORA-04068,修复它的唯一方法是重新连接会话或手动调用 DBMS_SESSION.RESET_PACKAGE() (但我不控制所有可能受影响的代码),否则每次调用时问题都会持续存在。

是否有任何数据库参数可以控制它并进行调整?该问题并不特定于任何特定的 PL/SQL 包,并且当它引用的内容发生更改时,它似乎可以由正常的包失效触发。

先感谢您。


Oracle 这样做是因为重新编译 PL/SQL 包会使正在使用的任何会话变量失效。

除了使用良好的部署实践之外,我们无能为力来避免这种情况。不要在数据库使用时部署更改,确保所有连接都正确断开等。在这个 CI/CD、零停机时间和其他令人兴奋的创新时代,说起来容易做起来难。

所以储物柜后面有一样东西:pragma serially_reusable;。该指令意味着包的状态在以下持续时间内保持不变单个服务器调用。例如,如果我们有一个 PL/SQL 块,它调用 SR 过程三次,则该过程更改的任何变量都将在这三个调用中保留该值。但是下次我们在同一会话中运行该块时,变量将被重置为其初始值。

可连续重用的 PL/SQL 有一些限制 - 例如,它不能在 SQL 查询中使用。但从您的角度来看,最大的吸引力在于不再出现 ORA-04068 或 ORA-04061 错误。没有会话状态,没有什么可以使之无效。

pragma serially_reusable必须在包级别、主体以及规范中声明。因此,您必须确保没有任何打包过程需要在服务器调用之间维护状态。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ORA-04061: 包体“PACKAGE.NAME”的现有状态已失效,但仍然存在 的相关文章

随机推荐