2016-08-04 10 views
0

Javaプログラムがストアドプロシージャを呼び出してファイルを解析し、テーブルの属性を読み込みます。これは特にソフト削除を実行するときに非常に時間がかかるステップです(古いレコードを更新するのではなく、同じファイルの新しいバージョンが入った場合は、古いレコードの削除フラグを設定します)。 Javaプログラムは、終了するまで待機する傾向があります。場合によっては、多数のファイルがdbにロードされると、javaプログラムは突然終了し、コアダンプを生成します。大きなワークフローの一環として、このジョブを終了しても残りのステップには影響しません。実行を続けると、別のコアダンプとhs_err_pidログファイルを使用して次のステップ(別のストアドプロシージャを呼び出す)で再度失敗します。ただし、ファイルをロードするストアドプロシージャは、数時間後に終了するまで続行されます。コアダンプのタイムスタンプは、Oracleがソフト削除を行っているときとまったく同じであることを示しています。JavaでOracleストアドプロシージャを呼び出すときにコアダンプを回避する方法

ログとコアダンプを読むと、何が問題になったのかが分かりません。私はgdbを使ってコアダンプをデバッグし、プロシージャの呼び出し中にエラーが発生したことだけを示しています。私の推測では、oracleがファイルをロードするのが忙しく(ソフト削除)、JVMがクラッシュしてコアダンプが発生する原因となっていたのは無意味でした。同様の理由から、このジョブの後のジョブは、依然としてオーバーロードされているため、dbとの通信に問題があります。

Oracle側でSQL例外が発生したため、何もキャッチすることはありません。 JVMがクラッシュするのを防ぐために、このような致命的なエラーを回避する方法はありますか?または、Oracleを聞くのではなくストアド・プロシージャが呼び出された後、プロシージャの終了時にのみ戻されるようにJavaに接続解除するようにJavaに指示する方法はありますか。ここで

は、私がプロシージャを呼び出すために使用するJavaコードです:

try { 
    CallableStatement stmt = conn.prepareCall("{call FILE_PROCESS.load_file(?,?,?,?,?,?,?,?,?)}"); 
    for (int i = 1; i < 10; i ++) { 
     stmt.setString(i, arr[i - 1]); 
    } 
    stmt.registerOutParameter(7, Types.VARCHAR); 
    stmt.registerOutParameter(8, Types.VARCHAR); 
    stmt.registerOutParameter(9, Types.VARCHAR); 
    stmt.executeUpdate(); 
    stmt.close(); 
    conn.close(); 
} 
catch (SQLException e) { 
    e.printStackTrace(); 
    System.exit(1); 
} 

EDIT: 別のファイル「hs_err_pid26342.log」も同時にシステムによって生成されました。私はその下にいくつか貼り付けた。それはSR_Handlerについて何か言います。このメソッドとは何ですか、どのように呼び出されますか?

# 
# A fatal error has been detected by the Java Runtime Environment: 
# 
# SIGSEGV (0xb) at pc=0x00002b95187851d3, pid=26342, tid=47919353368928 
# 
# JRE version: 7.0-b147 
# Java VM: Java HotSpot(TM) 64-Bit Server VM (21.0-b17 mixed mode linux-amd64 compressed oops) 
# Problematic frame: 
# V [libjvm.so+0x6f31d3] SR_handler(int, siginfo*, ucontext*)+0x43 
+2

この説明は意味をなさないと思われます。 Javaアプリケーションは、ストアド・プロシージャが戻るまでに長時間待つため、単にコア・ダンプを実行しません。最悪の場合、ある種のSQLタイムアウト例外が発生しますが、それはコアダンプにつながりません。プロシージャ・コールを非同期にするには、ストアド・プロシージャを実行するデータベースにジョブをサブミットし、結果をテーブルに書き込み、アプリケーションからそのテーブルをポーリングすることができますが、問題に影響することは明白ではありません。 –

+0

@JustinCave Javaがあまりにも長く待つかどうかはわかりません。おそらく、データベースが柔らかい削除のようなものをやって忙しすぎると、Oracleとの通信が失われていました。それは意味をなさないかもしれませんが、ソフト削除とJava側のコアダンプの間には明らかな相関があります。 – ddd

+0

待ち時間が長すぎたり、通信が失われても、コアダンプは発生しません。無期限に待機してJavaから呼び出すストアドプロシージャを記述すると、コアダンプは生成されません。 JVMは、プロシージャが実行されている間に何が行われているかについての洞察を持っていないので、コアダンプをプロシージャが行う特定のものと相関させることは意味がありません。これは誤った相関関係にあり、コアダンプをもう一度見て、デバッグを支援するためにアプリケーションサーバーをサポートする会社を関与させる必要があります。 –

答えて

0

ストアドプロシージャが呼び出されるのではなく、Oracleに耳を傾け である場合にのみ手順 終了返したら、私は、DB接続を切断するには、Javaを伝えることができますか。

DBMS_SCHEDULERを参照してください。あなたは、スケジューラのジョブにコード化され、その後、Javaはバックグラウンドタスクとしてそのジョブを実行するためにデータベースを言うだろうということだろう

BEGIN 
    file_load_stored_proc; 
END; 

を実行する代わりにJava以外

。データベースは別のデータベースセッションでジョブを開始し、制御をJavaプログラムに直ちに戻します。それが失敗した場合

BEGIN 
    DBMS_SCHEDULER.RUN_JOB('FILE_LOAD_JOB',false); 
END; 

あなたは電子メールを送信するためのスケジューラジョブを設定することができます(あるいはあなたがその通知をしたい場合はそれが成功した場合でも)。

PS。データベースの実行中にどこかで障害が発生していると思われ、Javaがコアダンプをきれいに処理していないのではないでしょうか。スケジューラジョブは、そこでの問題のより良い診断を可能にするはずです。

関連する問題