2016-09-16 1 views
0

概念を理解するのを手伝ってください。オラクルで再コンパイル中にオブジェクトがロックされる場合

以下のコードを使用して、無効なパッケージをプロシージャからコンパイルしようとしました。これは、次のエラー

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は、パッケージが再コンパイルされるプロシージャがパッケージでも使用されるテーブルを参照していることを認識しました。しかし、プロシージャ内のこのテーブルへのアクセスはパッケージを再コンパイルした後に行われます(言い換えれば、プロシージャとパッケージで使用されているテーブルに選択クエリが実行されます)

私に助けてください、エラー?あなたはセッションを変更すると思いますか?上記のコードの代わりにリセットパッケージが動作するか、同じエラーがスローされますか?

答えて

1

これがプロシージャ内で実行されている場合、現在実行されているため、自身を再コンパイルしたりデッドロックしようとしませんか?

あなたは手順を持っている場合、デッドロックの同じ種類が発生しますが、それ自体を削除しよう:

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

ハローマイケル、あなたの応答に感謝します。私は外部の別のプロシージャからパッケージを再コンパイルしています。私の知る限りでは、このような状況でデッドロックは起こらないと確信しています。しかし、私の質問は、パッケージが再コンパイルされるプロシージャは、パッケージでも使用されるテーブルを参照していることです。しかし、プロシージャ内のこのテーブルへのアクセスは、パッケージラインを再コンパイルした後に行われます(より明確にする:プロシージャとパッケージで使用されているテーブルに選択クエリが実行されます)。このため、デッドロックが発生する可能性がありますか? – Rachel

+0

私は再コンパイルがデータアクセスのデッドロックが発生する可能性のあるクエリを実行しないので、それは考えません。すべてのコードを解析し、検証し、すべてのコードを検証するだけです。 –

+0

ほとんどの人は試していませんディペンデンシー・ツリーを歩いて、もう何を再コンパイルするかを決定します。dbms_utility.compile_schema(your_user、false)のようなOracleの組み込み関数を使用します。スキーマyour_user内の無効なオブジェクトをすべて再コンパイルします。 –

関連する問題