简体   繁体   English

在Java中调用Oracle存储过程时如何避免核心转储

[英]How to avoid core dumps when calling Oracle stored procedure in Java

My java program calls a stored procedure to parse files and load attributes in tables. 我的Java程序调用存储过程来解析文件并在表中加载属性。 This is a very time consuming step especially when it is doing soft delete (if a newer version of the same file comes in, instead of updating the old record, we set the delete flag of old record). 这是一个非常耗时的步骤,尤其是在进行软删除时(如果出现了同一文件的较新版本,而不是更新旧记录,我们将设置旧记录的删除标志)。 The java program tends to wait until it finishes. Java程序倾向于等待直到完成。 In some occasions, when a great of number of files are being loaded to the db, java program would exit all of a sudden and generate core dumps. 在某些情况下,当大量文件加载到db时,java程序会突然退出并生成核心转储。 As a part of a big workflow, exiting of this job does not affect the rest of the steps. 作为大型工作流程的一部分,退出此工作不会影响其余步骤。 When it continues running, it would fail again at the next step (which also calls another stored procedure) with another core dump and hs_err_pid log file. 当它继续运行时,它将在下一步(又调用另一个存储过程)下再次失败,并带有另一个核心转储和hs_err_pid日志文件。 However the stored procedure to load files would keep going until it finishes after a few hours. 但是,加载文件的存储过程将继续进行,直到几个小时后完成。 The timestamps of the core dumps indicate they are exactly when Oracle is doing soft deletes. 核心转储的时间戳表明它们正是Oracle进行软删除的时间。

By reading the logs and core dumps, nothing tells me what went wrong. 通过阅读日志和核心转储,没有什么告诉我出了什么问题。 I debugged core dump using gdb and it only shows the error occurs during the call of the procedure. 我使用gdb调试了核心转储,它仅显示在过程调用期间发生的错误。 My guess is oracle was too busy loading files (soft deleting) and it was irresponsive at some point which caused my JVM to crash and thus the core dump. 我的猜测是oracle太忙于加载文件(软删除),并且在某些时候它没有响应,这导致我的JVM崩溃,从而导致核心转储。 For similar reason, the job after this one would also have problem communicating with db since it is still overloaded. 出于类似的原因,此任务之后的工作也将与db通信,因为它仍然超载。

Since there is SQL exception on Oracle side when it happens, there is nothing to catch. 由于发生这种情况时,Oracle方面存在SQL异常,因此没有什么要抓住的。 Is there a way to avoid the fatal error like this to prevent JVM from crashing? 有没有办法避免这样的致命错误,以防止JVM崩溃? Or how can I tell Java to disconnect db once the stored procedure is called rather than listening to Oracle and only returns when procedure finishes. 或者,如何告诉Java在调用存储过程后断开db的连接,而不是监听Oracle并仅在过程完成时才返回。

Here is the java code I use to call the procedure: 这是我用来调用该过程的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: Another file 'hs_err_pid26342.log' was also generated by system at the same time. 编辑:另一个文件'hs_err_pid26342.log'也由系统同时生成。 I pasted some of it below. 我在下面粘贴了一些。 It says something about SR_Handler. 它说了一些关于SR_Handler的信息。 What is this method, and how is it called? 这是什么方法,怎么称呼它?

#
# 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

how can I tell Java to disconnect db once the stored procedure is called rather than listening to Oracle and only returns when procedure finishes. 我该如何告诉Java在调用存储过程后断开db连接,而不是监听Oracle,并且仅在过程完成时返回。

Look at DBMS_SCHEDULER. 看一下DBMS_SCHEDULER。

Rather than the Java running 而不是Java运行

BEGIN
   file_load_stored_proc;
END;

you would have that coded into a scheduler job, then the java would tell the database to execute that job as a background task. 您会将其编码到调度程序作业中,然后Java会告诉数据库将该作业作为后台任务执行。 The database will start the job in a separate database session and pass control back to the Java program immediately. 数据库将在单独的数据库会话中启动作业,并将控制权立即传递回Java程序。

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

You can configure the scheduler job to send emails if it fails (or even when it succeeds if you want that notification). 您可以将计划程序作业配置为在失败时发送电子邮件(或者,如果您希望该通知成功则发送电子邮件)。

PS. PS。 I suspect a failure is occurring somewhere in the database execution and the Java is failing to cope with that cleanly giving the core dump. 我怀疑数据库执行中的某个地方发生了故障,而Java无法完全解决核心转储问题。 The scheduler job should allow better diagnosis of any problem there. 调度程序工作应该可以更好地诊断那里的任何问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM