2016-09-16 92 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中的所有无效对象。 –

相关问题