2016-08-04 8 views
0

Mein Java-Programm ruft eine gespeicherte Prozedur auf, um Dateien zu analysieren und Attribute in Tabellen zu laden. Dies ist ein sehr zeitraubender Schritt, besonders wenn es Soft Delete durchführt (wenn eine neuere Version der gleichen Datei kommt, anstatt den alten Datensatz zu aktualisieren, setzen wir das Lösch-Flag des alten Datensatzes). Das Java-Programm wartet normalerweise bis zum Ende. In einigen Fällen, wenn eine große Anzahl von Dateien in die db geladen wird, würde Java-Programm plötzlich beendet und Core-Dumps generieren. Als Teil eines großen Workflows wirkt sich das Beenden dieses Jobs nicht auf die restlichen Schritte aus. Wenn es weiter ausgeführt wird, würde es beim nächsten Schritt (der auch eine andere gespeicherte Prozedur aufruft) erneut mit einer anderen Protokolldatei für Kernspeicherauszug und hs_err_pid fehlschlagen. Die gespeicherte Prozedur zum Laden von Dateien würde jedoch weiterlaufen, bis sie nach einigen Stunden abgeschlossen ist. Die Zeitstempel der Core-Dumps zeigen an, dass sie genau dann ausgeführt werden, wenn Oracle Soft-Löschvorgänge ausführt.So vermeiden Sie Core-Dumps beim Aufruf der gespeicherten Oracle-Prozedur in Java

Durch das Lesen der Logs und Core Dumps sagt mir nichts, was schief gelaufen ist. Ich debuggte Core-Dump mit Gdb und es zeigt nur den Fehler auftritt während des Aufrufs der Prozedur. Meine Vermutung ist, dass Orakel zu sehr damit beschäftigt war, Dateien zu laden (soft deleting) und es zu irgendeinem Zeitpunkt nicht mehr reagierte, was meine JVM zum Absturz brachte und damit den Core Dump. Aus ähnlichen Gründen würde der Job nach diesem auch Probleme mit der Kommunikation mit db haben, da es immer noch überlastet ist.

Da es eine SQL-Ausnahme auf der Oracle-Seite gibt, wenn es passiert, gibt es nichts zu fangen. Gibt es eine Möglichkeit, den schwerwiegenden Fehler zu vermeiden, um zu verhindern, dass JVM abstürzt? Oder wie kann ich Java sagen, db zu trennen, sobald die gespeicherte Prozedur aufgerufen wird, anstatt auf Oracle zu hören, und nur zurückkehrt, wenn die Prozedur beendet ist.

Hier ist der Java-Code Ich verwende die Prozedur aufzurufen:

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: andere Datei 'hs_err_pid26342.log' wurde auch durch das System zur gleichen Zeit erzeugt. Ich habe etwas darunter eingefügt. Es sagt etwas über SR_Handler aus. Was ist diese Methode und wie heißt sie?

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

Diese Beschreibung scheint keinen Sinn zu ergeben. Eine Java-Anwendung wird keinen Core-Dump durchführen, weil sie zu lange auf die Rückgabe einer gespeicherten Prozedur wartet. Im schlimmsten Fall würden Sie eine SQL-Timeout-Ausnahme erhalten, aber das würde nicht zu einem Core-Dump führen.Sie könnten einen Job in der Datenbank senden, der die gespeicherte Prozedur ausführt, das Ergebnis in eine Tabelle schreiben und diese Tabelle aus der Anwendung abrufen, wenn der Prozeduraufruf asynchron sein soll, es aber nicht offensichtlich ist, dass das Ihr Problem beeinträchtigen würde. –

+0

@JustinCave Ich bin mir nicht sicher, ob Java zu lange wartet. Vielleicht hat es die Kommunikation mit Oracle verloren, wenn die Datenbank zu sehr damit beschäftigt ist, Dinge wie das Löschen zu tun. Es mag nicht sinnvoll sein, aber es gibt eine offensichtliche Korrelation zwischen Soft-Löschungen und Core-Dumps auf der Java-Seite. – ddd

+0

Wenn Sie zu lange warten oder die Kommunikation verlieren, wird kein Core Dump ausgelöst. Wenn Sie eine gespeicherte Prozedur schreiben, die einfach unbegrenzt wartet und diese von Java aufruft, wird kein Core Dump erzeugt. Die JVM hat keinen Einblick in das, was die Prozedur ausführt, während sie ausgeführt wird, so dass es keinen Sinn macht, einen Core-Dump mit etwas Spezifischem zu korrelieren, das eine Prozedur ausführt. Es scheint wahrscheinlicher, dass dies eine falsche Korrelation ist, und Sie müssen erneut auf den Core-Dump schauen und die Firma einbeziehen, die Ihren Anwendungsserver unterstützt, um beim Debuggen zu helfen. –

Antwort

0

, wie ich Java DB trennen sagen können, wenn die gespeicherte Prozedur anstatt hören Oracle genannt ist und nur zurückgibt, wenn Prozedur beendet.

Betrachten Sie DBMS_SCHEDULER. Vielmehr

als die Java-Lauf

BEGIN 
    file_load_stored_proc; 
END; 

Sie sich, dass in einen Scheduler-Job codiert haben, dann würde die Java die Datenbank sagen, dass Arbeit als Hintergrundaufgabe auszuführen. Die Datenbank startet den Job in einer separaten Datenbanksitzung und gibt die Steuerung sofort an das Java-Programm zurück.

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

Sie können den Scheduler Job konfigurieren E-Mails zu senden, wenn es fehlschlägt (oder auch dann, wenn es gelingt, wenn Sie diese Meldung wollen).

PS. Ich vermute, dass ein Fehler irgendwo in der Datenbankausführung auftritt und das Java nicht damit fertig wird, sauber den Core-Dump zu geben. Der Scheduler-Job sollte eine bessere Diagnose eines Problems dort ermöglichen.

Verwandte Themen