2016-08-08 17 views
2

Ich arbeite an einem Spiel, das auf einem Java-Server läuft. Ich verwende HikariCP für Datenbank-Pooling, die eine ausgezeichnete Bibliothek, aber es jetzt wirft den folgenden Fehler meiner Art und Weise:HikariCP Verbindungsleck

[Hikari housekeeper (pool HikariPool-0)] WARN com.zaxxer.hikari.pool.ProxyLeakTask - Connection leak detection triggered for connection [email protected], stack trace follows 
java.lang.Exception: Apparent connection leak detected 
    at nl.finicky.lemonade.database.Database.prepare(Database.java:43) 
    at nl.finicky.lemonade.rooms.RoomFactory.loadRoom(RoomFactory.java:25) 
    at nl.finicky.lemonade.rooms.RoomFactory.<init>(RoomFactory.java:20) 
    at nl.finicky.lemonade.Lemonade.main(Lemonade.java:30) 

Jetzt weiß ich, dass eine Verbindung Leck bedeutet, dass eine offene Verbindung schwebt irgendwo, aber ich kann nicht herausfinden, wie oder wo.

Das folgende ist eine Methode in meiner Datenbank-Klasse, in der der Fehler entsprechend dem Stack-Trace auftreten sollte.

public PreparedStatement prepare(String query) { 
    PreparedStatement statement = null; 

    try { 
     while (statement == null) { 
      statement = this.dataSource.getConnection().prepareStatement(query, 1); 
// The line triggering the error^

      if (statement != null) { 
       this.databasePool.getStorage(); 
      } 
     } 
    } catch (SQLException e) { 
     e.printStackTrace(); 
    } finally { 
     return statement; 
    } 
} 

Dies ist nur eine grundlegende Methode, um eine Aussage zu initiieren. Wenn dies angerufen wird, verwende ich es und dann resultSet.close(), preparedStatement.getConnection.close() und preparedStatement.close()

Immer noch sagt mir, dass die Verbindung offen ist.

Wie löse ich das? Vielen Dank!

Antwort

2

Anruf preparedStatement.getConnection.close() später wird nur eine andere Verbindung erhalten und schließen Sie es.

Sie können nicht tun, was Sie mit dieser Art von Muster zu tun versuchen. Der Aufruf this.dataSource.getConnection().prepareStatement(...) ruft eine Verbindung aus dem Pool ab und verwirft den Verweis darauf, wonach niemand ihn schließen kann. Und Sie können die Verbindung in dieser Methode nicht schließen, auch wenn Sie einen Verweis darauf beibehalten haben, denn dann wäre das zurückgegebene PreparedStatement unbrauchbar.