2015-03-17 4 views
2

Предположим, у нас есть пакет ПАКЕТПочему выполнение этого блока никогда не заканчивается?

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; 

Почему делает выполнение блока

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

не закончится (сессия, кажется, висит)? Однако отдельное выполнение первой и второй строк (в разных анонимных блоках) является успешным.

ответ

4

Пакет в использовании, что означает, что instance еще активирован. Итак, если он не был убит, вы не можете изменить его состояние.

При вызове процедуры или любой сохраненной функции блокировка получает этот сеанс над этим состоянием объекта. Если вызывающий абонент не завершит работу модуля, блокировка останется активной.

В вашем случае вы пытаетесь изменить пакет в том же блоке PL/SQL, который вызвал его. Это результат с deadlock. Блок PL/SQL пытается динамически выполнить DDL, но есть блокировка уже на месте, когда пакет сначала вызван!

Пожалуйста, обратите внимание, что же PL/SQL можно еще назвать пакет после этого динамического DDL (Это может быть DROP тоже!). Поэтому для обеспечения согласованности блокировка не будет выпущена, если весь PL/SQL не будет завершен!

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

Где-а, при вызове в блоке отдельныйPL/SQL, замок будет уже выпущен. Перед вызовом DDL.

Попытка запуска этого SQL в другой сессии.

select * from v$access where object = 'PACK'; 
Смежные вопросы