2011-02-03 6 views
2

この状況を想像してみてください。私はpl/sqlモジュールに変更を加え、それを再コンパイルしても問題ありません。エラーはありません。 その後、Tomcat上で動作するアプリケーションのGUI画面にアクセスしようとしました。この画面では、oracleデータベースのpl/sqlモジュールがコールされます。Tomcatはキャッシュされたバージョンのpl/sqlモジュールを使用しますか?

私はデータを処理することのPL/SQLモジュールと呼ばれている必要がありますフォームを送信すると、私は

ORA-20001: ORA-06508: PL/SQL: could not find program unit being called 

このエラーが出る私は$ USER_OBJECTS内のすべてのパッケージをチェックし、INVALIDの状態には何もありません。

Tomcatを再起動してから作業を開始します。これは、初めてTomcatが使用していたパッケージへのキャッシュされた参照を効果的に削除したときに、パッケージを再コンパイルしたときに意味がありますか?

データベースへの接続は、JDBCおよびDBCP接続プールを介して行われます。再コンパイルで接続が無効になることはありますか?

答えて

3

この問題はJDBC接続プールで発生し、Tomcatだけでなく、JDBC接続プールを使用するすべてのアプリケーションサーバーで発生する問題です。接続プールは、次の要求の準備ができたプール内のいくつかの接続を開いたままにします。 PL/SQLパッケージが接続によって参照され、再コンパイルされた場合、そのパッケージへの次回のコールではORA-06508エラーが発生します。これは、直接呼び出したパッケージだけでなく、呼び出しスタック内のどこにでも影響を与えます。

これを解決するには、Weblogicなどのアプリサーバーに定期的に呼び出されるテストメソッドがあります。テストが失敗した場合、接続はプールから削除されるか、何らかの方法でリフレッシュされます。 Tomcatがどのようなメカニズムを持っているのかよく分かりません。

これに対処する別の方法は、JDBCコールの最初のメソッド呼び出しとしてdbms_session.reset_packageを呼び出すことです。これにより、セッション中のパッケージ状態がクリアされます。このアプローチは、パフォーマンス上のオーバーヘッドとパッケージスコープの変数がリセットされ、パッケージの初期化ブロックを再度呼び出す必要があり、別のパフォーマンスが低下するため推奨されません。

問題があり、不正な接続を削除する方法がない場合は、プール内の接続に同じ例外が発生するため、接続プール全体をリセットする必要があります。

+0

私はちょうどチェックしました。 Tomcat接続プールは、テストクエリを使用して接続の妥当性をテストできます。ありがとう – ziggy

2

この画面では、 oracleデータベースのpl/sqlモジュールがコールされます。

いいえ、ありません。 Tomcatでサーブレットベースのweb-appを実行していると仮定すると、ブラウザーは関連するサーブレットを呼び出すTomcatに要求を送信し、web-app内のいくつかのJavaクラスはpl/sqlプログラムをCallableStatementとして実行します。

JavaクラスがCallableStatementを実行する方法と、その参照を保持しているか、実行するたびにその準備をするかどうかの鍵です。あなたはこれについてどんな光を放つことができますか?

編集:
Oracle JDBCドライバは、問題の原因となっている可能性のある文キャッシュを実行できると考えています。ドライバのドキュメントを読んで詳細を入手してください。

+0

CallableStatementは、リクエストごとに用意されています。リクエストの最後に閉じられます。 Connectionオブジェクトは、プールに返されるときにクローズされません。 – ziggy

+0

Oracle JDBCドライバがそれをキャッシュしている可能性があります。 – Qwerky

+0

正確にはキャッシュされますか? pl/sqlモジュールを呼び出す文をキャッシュしますか?これには参照が含まれていますか?それが単なるステートメントの場合、再コンパイルはどのようにこのステートメントを無効にしますか? – ziggy

0

あなたは通常、取得しているエラーは、いずれかのストアドプロシージャ/パッケージことを示しています

1)名前で存在していませんが、あなたが

2)Javaクラスから(とそれを呼び出すようにしようとしています)は、実行しようとしている(JDBC接続で定義されている)ユーザーに対して、EXECUTE特権を与えられていない

3)名前だけで実行されている場合(すなわち、スキーマが前に付いていない場合)

4)正しい数と種類のパラメータを持たないで呼び出される

関連する問題