Ошибка ORA-04068: existing state of packages has been discarded — решение
- Пользователи или фоновые процессы внезапно получают ошибку
ORA-04068: existing state of packages has been discarded. - В цепочке ошибок присутствуют коды
ORA-04061(existing state of package has been invalidated) иORA-04065. - Вызов хранимых процедур падает после обновления кода объектов на рабочей базе.
1. Поиск инвалидных объектов в схеме
SELECT owner, object_name, object_type, status
FROM dba_objects
WHERE status = 'INVALID' AND owner = 'SCHEMA_NAME';2. Компиляция всех инвалидных объектов схемы
Используйте стандартную системную утилиту Oracle:
EXECUTE UTL_RECOMP.RECOMP_PARALLEL(4, 'SCHEMA_NAME');
-- Или для конкретного пакета:
ALTER PACKAGE schema_name.package_name COMPILE;
ALTER PACKAGE schema_name.package_name COMPILE BODY;3. Использование прагмы SERIALLY_REUSABLE
Если пакет не должен хранить состояние между вызовами в сессии, добавьте в заголовок и тело пакета:
PRAGMA SERIALLY_REUSABLE;4. Переподключение сессий приложения
При перекомпиляции пакета с глобальными переменными все открытые сессии обязаны переподключиться для повторной инициализации состояния пакета.
Частые вопросы (FAQ)
Почему перекомпиляция пакета ломает работающие сессии?
Если в спецификации или теле пакета объявлены глобальные переменные уровня пакета, Oracle хранит их состояние в PGA каждой сессии. При изменении сигнатуры пакета старое состояние становится невалидным, и Oracle сбрасывает его с ошибкой ORA-04068.
Что произойдет при повторном выполнении того же запроса после ORA-04068?
Второй вызов выполнится успешно, так как при первой ошибке Oracle уже очистил старое состояние в PGA и готов инициализировать новое.
Как выполнять релизы PL/SQL без генерации ORA-04068 у пользователей?
Используйте механизм Edition-Based Redefinition (EBR), позволяющий бесшовно версионировать код пакетов без блокировки активных пользователей.
Помогает ли перекомпиляция только BODY избежать ошибки ORA-04068?
Если тело пакета не содержит глобальных переменных, изменение только BODY не инвалидирует зависимые объекты и сессии. Но если переменные есть, сессия все равно будет сброшена.