On one of Oracle DB instances I am working on I am observing a different than normal behavior when recompiling packages.
Typically, (as in question Frequent error in Oracle ORA-04068: existing state of packages has been discarded) following error on first call is expected after PL/SQL package recompilation:
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
But the second call should work fine, assuming the package has no errors of course. This behavior was present previously in that environment. In the meantime we upgraded from 11g R2 to 12c R1, and enabled edition based redefinition.
Now the problem I am experiencing is that I keep getting just:
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
So no ORA-04068 anymore, and only way to fix it is to reconnect the session or calling DBMS_SESSION.RESET_PACKAGE() manually (but I don’t control all code that may be affected anyway), otherwise the problem persists on every call.
Are there any DB parameters that control this that could got tweaked? The problem is not specific to any particular PL/SQL package and it seems that it can be triggered by normal package invalidation when something it references, changes.
Thank you in advance.
Oracle делает это, потому что перекомпиляция пакета PL / SQL делает недействительными все используемые переменные сеанса.
Мы мало что можем сделать, чтобы избежать этого, кроме как с помощью передовых методов развертывания. Не развертывайте изменения, пока база данных используется, убедитесь, что все соединения должным образом отключены и т. д. Легче сказать, чем сделать в наш век CI / CD, нулевого времени простоя и других интересных инноваций.
Итак, в задней части шкафчика есть одна вещь: pragma serially_reusable;. Эта инструкция означает, что состояние пакета сохраняется в течение один вызов сервера. Например, если у нас есть блок PL / SQL, который трижды вызывает процедуру SR, любые переменные, измененные этой процедурой, будут поддерживать значение во всех трех вызовах. Но в следующий раз, когда мы запустим блок — в том же сеансе — переменные будут сброшены до своих начальных значений.
Есть несколько ограничений для последовательного многократного использования PL / SQL — например, его нельзя использовать в SQL-запросах. Но с вашей точки зрения больше всего привлекает отсутствие ошибок ORA-04068 или ORA-04061. Нет состояния сеанса, нечего аннулировать.
Pragma serially_reusable должен быть объявлен на уровне пакета, как в теле, так и в спецификации. Таким образом, вы должны быть уверены, что ни одна из упакованных процедур не должна поддерживать состояние между вызовами сервера.
Error Message
When accessing the Spatial Type for Oracle using SQL, the following error message is displayed:
ORA-04061: existing state of has been invalidated
ORA-04061: existing state of package body «SDE.ST_GEOMETRY_SHAPELIB_PKG» has been invalidated
ORA-06508: PL/SQL: could not find program unit being called
Note:
The name of the package body (SDE.ST_GEOMETRY_SHAPELIB_PKG) may be different from time to time, but the cause of the error is the same. The error number and format of the error message will not change.
Cause
Oracle has discovered a package or type body is invalid, and the object cannot be automatically recompiled. This issue has been identified on some Oracle servers where one database object has changed and has dependent database objects which become invalid.
Solution or Workaround
The invalid object needs to be recompiled to become valid again. Oracle 10g includes a mechanism to recompile some invalid objects when they are accessed for the first time. However, this mechanism does not always work and errors of this sort can occur. If this error is encountered, the invalid packages and any invalid type bodies can be manually recompiled.
After recompiling, be sure to start a new Oracle session before verifying that recompiling solved the problem.
To find invalid objects owned by the user SDE, connect to Oracle with SQL*Plus and execute the following statement:
SELECT OBJECT_NAME, OBJECT_TYPE
FROM USER_OBJECTS
WHERE OBJECT_TYPE IN (‘PACKAGE’, ‘PACKAGE BODY’, ‘TYPE’, ‘TYPE BODY’)
AND STATUS = ‘INVALID’;
To recompile a type body, use the following command:
ALTER TYPE <object_name> COMPILE BODY;
To recompile a package body, use the following command:
ALTER PACKAGE <object_name> COMPILE BODY;
Last Published: 5/5/2016
Article ID: 000010831