2016-09-16 91 views
0

請幫我理解這個概念。什麼時候在oracle中重新編譯時鎖定對象

我試圖從使用下面的代碼的過程編譯一個無效的軟件包。它被扔以下錯誤

ORA-04021:在等待鎖定對象

for cur_rec in (select object_name, object_type 
       from user_objects 
       where object_type in ('PACKAGE', 'PROCEDURE', 'FUNCTION','PACKAGE BODY') 
       and status != 'VALID') 
loop 
    begin 
    if cur_rec.object_type != 'PACKAGE BODY' then   
     execute immediate 'ALTER '||cur_rec.object_type||' usr.'||cur_rec.object_name||' COMPILE'; 
    else 
     execute immediate 'ALTER PACKAGE usr.'||cur_rec.object_name||' COMPILE BODY'; 
     dbms_output.put_line('Package recompiling finish'); 
    end if; 

    end; 
end loop; 

我已經看到了這個網站的所有建議發生超時。我檢查了會話瀏覽器,但沒有其他活動會話提到這個包。

因此檢查了dba_dependencies,並且實現了程序包重新編譯的過程引用了一個也在包中使用的表。但是這個表訪問過程是在重新編譯包之後出現的(換句話說,在表中有一個select查詢被使用在過程和包中)

請幫助我們,這是爲什麼錯誤?你會覺得改變會議。重置包而不是上面的代碼會工作或拋出相同的錯誤?

回答

1

如果這是在一個過程內部運行,它不會嘗試重新編譯自身和死鎖,因爲它當前正在運行?

如果你有一個程序試圖刪除本身也會發生同一類的僵局:

CREATE OR REPLACE PROCEDURE calc_bonus (emp_id NUMBER) AS 
BEGIN 
    EXECUTE IMMEDIATE 'DROP PROCEDURE calc_bonus'; -- deadlock! 
END; 
/
+0

喂邁克爾,感謝您的答覆。我正在重新編譯來自另一個外部程序的程序包。據我所知,我相信在這種情況下不會出現僵局。但我的問題是:程序包重新編譯的過程是引用一個也在包中使用的表。但是在這個過程中的表訪問是在重新編譯包行之後進行的(更清楚的是:在過程和包中也使用了在表上激發的select查詢)。由於這可能會導致死鎖? – Rachel

+0

我不會這麼認爲,因爲重編譯並不執行查詢可能發生數據訪問死鎖 - 它只是解析引用,解析和驗證所有的代碼等。 –

+0

我也應該注意到,大多數人不會嘗試要遍歷依賴樹來找出重新編譯的內容 - 他們只是使用Oracle內置插件,如:dbms_utility.compile_schema(your_user,false);重新編譯模式your_user中的所有無效對象。 –

相關問題