powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
25 сообщений из 40, страница 1 из 2
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #37560751
anvano
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наткнулся на странное (для меня) поведение - не могу в документации найти почему работает именно так.

Дано: два пакета с глобальными переменными (то бишь не stateless)

Первый:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
CREATE OR REPLACE PACKAGE pk_test IS
  PROCEDURE some_test;
END;  
CREATE OR REPLACE PACKAGE BODY pk_test IS
  g_var  NUMBER:=0;
  PROCEDURE some_test IS
  BEGIN
    g_var:=1;
    dbms_output.put_line('This is a test from pk_test! var='||g_var);
  EXCEPTION WHEN OTHERS THEN
    dbms_output.put_line('This is exception'||SQLERRM);
    RAISE;  
  END;  
END;  



Второй:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
CREATE OR REPLACE PACKAGE pk_test2 IS
  PROCEDURE some_test;
END;  
CREATE OR REPLACE PACKAGE BODY pk_test2 IS
  g_var  NUMBER:=0;
  PROCEDURE some_test IS
  BEGIN
    dbms_output.put_line('pk_test2 calling pk_test:');
    pk_test.some_test;
    dbms_output.put_line('pk_test2 successfuly called pk_test');
  EXCEPTION WHEN OTHERS THEN
    dbms_output.put_line('This is exception'||SQLERRM);
    --RAISE;  
  END;  
END; 



Вызываем метод второго пакета - получаем
Код: plaintext
1.
2.
3.
4.
5.
SQL> call pk_test2.some_test();

pk_test2 calling pk_test:
This is a test from pk_test! var=1
pk_test2 successfuly called pk_test


Типа всё окей, работает.

Теперь в другой сессии меняю значение переменной в теле первого пакета pk_test - с 1 на 2 и перекомпилирую тело,
для текущей сессии состояние пакета сбрасывается

Если вызвать напрямую тот пакет, который изменили, то получим:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
SQL> call pk_test.some_test();
call pk_test.some_test()
     *
ERROR at line 1:
ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package body "ANVANO.PK_TEST" has been invalidated
ORA-04065: not executed, altered or dropped package body "ANVANO.PK_TEST"



после чего пакет автоматически пересобирается и повторный вызов проходит успешно.

Меняем снова тело первого пакета, перекомпилируем body.
Теперь если вызывать его через второй пакет, то постоянно получаем:
Код: plaintext
1.
2.
3.
SQL> call pk_test2.some_test();
pk_test2 calling pk_test:
This is exceptionORA-06508: PL/SQL: could not find program unit being called



и пересборки первого пакета не происходит вообще, сколько бы раз мы не вызывали второй пакет, вызывающий первый.

Однако если во втором пакете в секцию обработки исключения добавить RAISE - то мы опять получим
ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package body "ANVANO.PK_TEST" has been invalidated

и всё пересоберётся. Если добавить не просто RAISE, а какое-то конкретное исключение типа RAISE no_data_found - то пересборка опять не происходит.

На чем основано такое поведение Oracle? Почему в одном случае первый пакет пересобирается после первого обращения к нему, а в другом случае не пересобирается никогда?






--------------------------------------------------------------
Запомните, товарищи офицеры, чтобы ничего не делать, надо уметь делать все.
...
Рейтинг: 0 / 0
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #37560814
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Думаю, для ответа стоит прикинуть, зачем вообще нужна ORA-4068, почему бы просто не перекомпилить тихой сапой и не работать дальше. Ответ на этот вопрос: потому что теряется состояние пакета, и если приложение об этом не узнает, оно, продолжая работу, может натворить дел. Теперь следующий вопрос: почему последующие обращения проходят успешно. Ответ: потому, что требовать глобального переподключения - слишком жестоко, неудобно для клиентов. С другой стороны после 4068 как минимум откатилась транзакция, есть надежда, что клиент обработал эту ошибку, и как следствие, начавшаяся следующая транзакция с большой вероятностью пройдёт правильно.

А отсюда получается ответ на Ваш вопрос: именно потому, что клиент должен узнать (и узнаёт) об этой ошибке.
...
Рейтинг: 0 / 0
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #37560835
anvano
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну тогда может кто-то посоветует, что делать если в некотором триггере на таблице вставлен анонимный PL/SQL блок для вызова некритичной для бизнес процесса функции стороннего пакета:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
CREATE OR REPLACE TRIGGER ....

bla bla

   BEGIN
      pk_test.some_test;
   EXCEPTION WHEN OTHERS THEN
      log_message('Error call PK_TEST  in trigger '||sqlerrm);
   END;

END;



Исключение специально гасится, т.к. выполнение метода pk_test.some_test не должно влиять на вставку / апдейты строк таблицы в рамках основного бизнес процесса. Оно желательно, но не обязательно. Так вот после перекомпиляции тела пакета PK_TEST в лог начинает сыпаться вышеописанная ошибка ORA-06508: PL/SQL: could not find program unit being called

Естественно метод прекращает отрабатывать и если не переконнектить сессию БД, в которой работает триггер - то вызова пакета PK_TEST больше никогда не происходит вообще никогда.

Какие тут могут быть варианты, кроме передёргивания сессии ? Или вообще без вариантов, тронул пакет и всё, хана?
...
Рейтинг: 0 / 0
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #37560842
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
anvanoи пересборки первого пакета не происходит вообщеПрежде всего не путай инвалидацию программной единицы (dependenies) и инвалидацию состояния пакета (ORA-04061).
Первая всегда пытается автоматически "исправиться" рекомпиляцией.

Состояние же пакета может быть сброшено только после возврата управления от сервера к клиенту (после завершения server call), но не раньше:
явно на уровне пакета (SERIALLY_REUSABLE Pragma)

явно на уровне сессии (dbms_session.reset_package/modify_package_state)

неявно на уровне сессии, если server call завершился с ORA-04068. Если ORA-04068 не возвращается клиенту, то обращение к пакету будут всё равно обламываться по ORA-06508. Но состояния других пакетов останутся несброшенными и ими можно (нужно ли?), при необходимости воспользоваться. Состояние пакетов сбрасывается, даже если искуственно породить прохождение -4068 от сервера к клиенту:
Код: plaintext
1.
declare e4068 exception; pragma exception_init(e4068, -4068); begin raise e4068; end;
...
Рейтинг: 0 / 0
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #37560876
sipher too
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
anvano,

Курим доку, например Oracle 9i Program With PL-SQL, последняя глава, разделы "Unsuccessful Recompilation" и "Successful Recompilation".

А кто будет перекомпилировать второй пакет, Пушкин?
...
Рейтинг: 0 / 0
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #37560884
anvano
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем спасибо, особенно Elic. Стало понятнее про сброс состояния пакета и в какую сторону копать доки.
...
Рейтинг: 0 / 0
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #37562251
_танкист
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
а может кто-то чуть подробней расшифровать вот эту часть феномена:
Меняем снова тело первого пакета, перекомпилируем body.
Теперь если вызывать его через второй пакет, то постоянно получаем
...
Рейтинг: 0 / 0
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #37562312
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #37799455
Фотография Есть вопрос
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elicanvanoи пересборки первого пакета не происходит вообщеПрежде всего не путай инвалидацию программной единицы (dependenies) и инвалидацию состояния пакета (ORA-04061).
Первая всегда пытается автоматически "исправиться" рекомпиляцией.

Состояние же пакета может быть сброшено только после возврата управления от сервера к клиенту (после завершения server call), но не раньше:
явно на уровне пакета (SERIALLY_REUSABLE Pragma)

явно на уровне сессии (dbms_session.reset_package/modify_package_state)

неявно на уровне сессии, если server call завершился с ORA-04068. Если ORA-04068 не возвращается клиенту, то обращение к пакету будут всё равно обламываться по ORA-06508. Но состояния других пакетов останутся несброшенными и ими можно (нужно ли?), при необходимости воспользоваться. Состояние пакетов сбрасывается, даже если искуственно породить прохождение -4068 от сервера к клиенту:
Код: plsql
1.
declare e4068 exception; pragma exception_init(e4068, -4068); begin raise e4068; end;



Здравствуйте!
Подскажите, пожалуйста, а где в документации описан третий вариант?
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #38889640
Melkomyagkii_newbi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elicanvanoи пересборки первого пакета не происходит вообщеПрежде всего не путай инвалидацию программной единицы (dependenies) и инвалидацию состояния пакета (ORA-04061).
Первая всегда пытается автоматически "исправиться" рекомпиляцией.

Состояние же пакета может быть сброшено только после возврата управления от сервера к клиенту (после завершения server call), но не раньше:
явно на уровне пакета (SERIALLY_REUSABLE Pragma)

явно на уровне сессии (dbms_session.reset_package/modify_package_state)

неявно на уровне сессии, если server call завершился с ORA-04068. Если ORA-04068 не возвращается клиенту, то обращение к пакету будут всё равно обламываться по ORA-06508. Но состояния других пакетов останутся несброшенными и ими можно (нужно ли?), при необходимости воспользоваться. Состояние пакетов сбрасывается, даже если искуственно породить прохождение -4068 от сервера к клиенту:
Код: plsql
1.
declare e4068 exception; pragma exception_init(e4068, -4068); begin raise e4068; end;




Апну. А на уровне системы что можно что-то сделать?
...
Рейтинг: 0 / 0
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #38889666
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Melkomyagkii_newbiчто можно что-тоЧто-то чтобы что?
...
Рейтинг: 0 / 0
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #38889735
Melkomyagkii_newbi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-2-Melkomyagkii_newbiчто можно что-тоЧто-то чтобы что?

Торопился. У нас похожая проблема. Есть два пакета с глобальными переменными. Сейчас веб приложение ловит на них ORA-04068: existing state of packages has been discarded
После ребута коннекшн пула первый раз процедура из одного и пакетов отрабатывает, потом перестает работать. Код поправить возможности нет(
С ТОАДа причем процедуры обоих пакетов без проблем дергаются.
...
Рейтинг: 0 / 0
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #38889772
Melkomyagkii_newbi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Melkomyagkii_newbi-2-пропущено...
Что-то чтобы что?

Торопился. У нас похожая проблема. Есть два пакета с глобальными переменными. Сейчас веб приложение ловит на них ORA-04068: existing state of packages has been discarded
После ребута коннекшн пула первый раз процедура из одного и пакетов отрабатывает, потом перестает работать. Код поправить возможности нет(
С ТОАДа причем процедуры обоих пакетов без проблем дергаются.

Из тоада воспроизводится.. Зависит от порядка вызова пакетов. Если начать с одного, то сколько не вызывай получаю ошибку, если вызвать второй, то после этого и первый нормально вызывается.
...
Рейтинг: 0 / 0
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #38889775
Melkomyagkii_newbi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-2-Melkomyagkii_newbiчто можно что-тоЧто-то чтобы что?

Собственно чтобы сброить стэйт пакета
...
Рейтинг: 0 / 0
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #38889783
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Melkomyagkii_newbiконнекшн пулаStateful Connection Pool?!
...
Рейтинг: 0 / 0
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #38889799
Melkomyagkii_newbi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ElicMelkomyagkii_newbiконнекшн пулаStateful Connection Pool?!

Да вот фиг пойми. Когда они убили пул, я в базе убедился, что сессии отвалились
...
Рейтинг: 0 / 0
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #38889803
Melkomyagkii_newbi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Melkomyagkii_newbiElicпропущено...
Stateful Connection Pool?!

Да вот фиг пойми. Когда они убили пул, я в базе убедился, что сессии отвалились

Хм, понял что не в тему ответил, не понял вас если честно.. у меня ведь воспроизводится проблема..
...
Рейтинг: 0 / 0
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #38889892
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Melkomyagkii_newbiне понял вас если честно..нужно ли сохранять значения глобальных переменных между вызовами.
...
Рейтинг: 0 / 0
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #38889893
Melkomyagkii_newbi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-2-Melkomyagkii_newbiне понял вас если честно..нужно ли сохранять значения глобальных переменных между вызовами.

А ну, да, должно быть не нужно, пул же. Понял теперь. Но так сложилось "исторически" - отжали проект у одной индийской компании.
...
Рейтинг: 0 / 0
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #38890073
anvano
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У нас всё в итоге решилось прокидыванием эксепшена ORA-04068 наружу "до клиента".

До этого как оказалось, он в некоторых местах гасился в обработчиках WHEN OTHERS, что приводило к такой вот хрени как перманентный ORA-06508. Теперь всё работает как часы.

А еще в большей части пакетов вообще удалось отказаться от глобальных переменных.
В итоге теперь накатывание такого тела пакета вообще не приводит ни к каким последствиям типа ORA-04068.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #39408921
Gogol
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день.
Подскажите, если вынести в глобальные переменные пакета константы:

Код: plsql
1.
2.
3.
F_NEW CONSTANT  VARCHAR2(20) =  'F_NEW';
F_COM CONSTANT  VARCHAR2(20) =  'F_COM';
ROUTE_DOC_NEW CONSTANT PLS_INTEGER  := fnc_get_route(F_NEW, FLDR_COM);



Указанные выше проблемы возникнут, или при описании CONSTANT, изменение стояния пакета не приведет к отваливанию сеcсии?
...
Рейтинг: 0 / 0
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #39408923
Gogol
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код:

Код: plsql
1.
2.
3.
F_NEW CONSTANT  VARCHAR2(20) =  'F_NEW';
F_COM CONSTANT  VARCHAR2(20) =  'F_COM';
ROUTE_DOC_NEW CONSTANT PLS_INTEGER  := fnc_get_route(F_NEW, F_COM);
...
Рейтинг: 0 / 0
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #39409099
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GogolУказанные выше проблемы возникнутКакие?
http://www.bugtraq.ru/forum/faq/general/smart-questions.html] RTFM
...
Рейтинг: 0 / 0
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #39409161
fortnet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Gogol,

Почему нет? Думаю, константа или не константа - не повлияет на механизм , управляющий состоянием пакета.
...
Рейтинг: 0 / 0
Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
    #39409181
Vint
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Gogol,
а не могли бы вы обьяснить зачем вам константы в пакете?
почему надо именно F_NEW CONSTANT VARCHAR2(20) = 'F_NEW'; и потом использовать переменную F_NEW вместо того чтобы просто не написать 'F_NEW'?
хоть раз за все время проекта такая константа менялась и вам действительно приходилось менять ее значение после выкатки в продакшн?
...
Рейтинг: 0 / 0
25 сообщений из 40, страница 1 из 2
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Автоматическая перекомпиляция при обращении к пакету. Ткните носом в доку.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]