Reicht finally nicht um DB connections zu schließen in (altem) Java?

PFEdi

Mitglied
Ich habe hier eine Problem mit einem archäologischen Stück Java Software.
Das ganze ist in einem einfachen teil Code – Über sein Servlet wird eine Methode aufgerufen, die eine Datenbank abfrage durchführt und dann einen wert zurück liefert.

Jetzt ist das Problem das die DB connections nicht geschlossen werden, und daher irgendwann auslaufen.
Was mir gesagt wurde wo der Code im Einsatz ist - das die das schon kennen, und eine alter Java Bug ist, das unter last das finally nicht zum Zug kommt ..

Da frage ich mich - kann den das stimmen?
Was ich gelesen habe, kommt finally immer dran, außer man beendet den Thread komplett - System.exit(), OOM, JVM oder gar OS crash.
Aber sonnst sollte es immer funktionieren.

Oder kennt jemand tatsächlich einen BUG in alten versionen (kann mir vorstellen, dass das noch 1er versionen dort sind)???
Was meint ihr? Oder habt ihr andere Ideen?

LG,
Paul

Java:
public int checkDb() {
    Connection con = null;
    int retVal = -1;

    try {
        con = getConnection(); // java.sql.Connection
        final CallableStatement cstmt = con.prepareCall("{call DB.CheckDb()}");
        // ...
        // ...
       
        return retVal;
    } catch (SQLException e) {
        // Logging
    } finally {
        if (con != null) {
            try {
                con.close();
            } catch (SQLException e) {
                // Logging
            }
        }
    }

    return retVal;
}

Gut heute würde man es eher so um schreiben (ja eigentlich ganz anders, aber ihr wisst hoffentlich was ich meine.
Java:
public int checkDb() {
    Connection con = null;
    int retVal = -1;

    try (Connection = getConnection()) {
        con = getConnection(); // java.sql.Connection
        final CallableStatement cstmt = con.prepareCall("{call DB.CheckDb()}");
        // ...
        // ...
       
        return retVal;
    } catch (SQLException e) {
        // Logging
    }
   
    return retVal;
}
 
das unter last das finally nicht zum Zug kommt ..
Nein. finally ist Teil des Programmablaufs, dort muss das Teil vorbeikommen. finalizer hingegen ist eine komplett andere Sache...

Was natuerlich sein koennte ist dass unter hoher Last viele gleichzeitige Verbindungen aufgemacht werden und diese nicht schnell genug wieder geschlossen werden koennen. Also wenn du 500 Clients auf das Ding loslaesst, gleichzeitig, werden auch 500 Verbindungen aufgemacht, gleichzeitig, und da spielt das final keine Rolle weil dort wa der Ablauf noch gar nicht.

So als Anmerkung, try with resources kompiliert auch zu nichts anderem als deinem ersten Beispiel, das wird vom Kompilierer umgewandelt.

Was natuerlich auch ein koennte ist dass der Scheduler vom Betriebssystem so schlecht ist und die einzelnen Threads einfach nicht d'ran kommen um das finally auszufuehren weil neuere Threads eine hoehere Prioritaet haben. Das waere aber schon ein beeindruckender Sonderfall.

Wenn ihr die Moeglichkeit habt das zu suchen, wuerde ich in den Rueckgabewert von getConnection() kapseln so dass man die genaue Lebenszeit einer Verbindung im Log sehen kann. Dann kann man sehr gut sagen wieviele Verbindungen tatsaechlich gleichzeitig leben und wie lange diese leben.
 
Zuletzt bearbeitet:
So einfach ist das nicht. Normalerweise werden die Connections vom Server verwaltet. Endgültig entscheidet der Connection-Pool wieviele Connections offen sind. Allerdings ist in dem Code nicht zu sehen, wie die Connections verwaltet werden.
 
Weiterhin: wie heisst die verwendete Datenbank ? Immerhin könnte der Fehler (auch) im verwendeten Treiber liegen.
 

Neue Themen


Zurück
Oben