Apache DBCP: Reconnect nach Timeout?

Status
Nicht offen für weitere Antworten.

tfa

Top Contributor
Moin!

Ich benutze einen DBCP-Pool in einem kleiner Server-Programm (Standalone, kein Application-Server):
Code:
private void setup() {
    try {
        Class.forName("com.mysql.jdbc.Driver");
    }
    catch (ClassNotFoundException e) { ... }
    
    this.pool = new GenericObjectPool(null);
    
    DriverManagerConnectionFactory cf = new DriverManagerConnectionFactory(this.jdbcUrl, "name", "passwort");    
    new PoolableConnectionFactory(cf, this.pool, null, "SELECT * FROM schema_info", false, true);    
    new PoolingDriver().registerPool("pool", this.pool);    
}


// Benutzung (ohne weiter Fehlerbehandlung):

Connection con = DriverManager.getConnection("jdbc:apache:commons:dbcp:pool");

Statement stmt = con.createStatement();
try {
    ResultSet rset = stmt.executeQuery("SELECT ....");
    ...
}
finally {
    stmt.close();
    con.close();
}

setup() wird einmal zu Beginn aufgerufen zur Initialisierung des Connection-Pools.
Das läuft auch alles wunderbar. Nur wenn die Connection bzw. der Pool lange Zeit (so 10-12 Stunden) nicht
benutzt wurde (MySQL die Verbindung also per Timeout dicht macht), kommt beim nächsten Versuch die Connection zu benutzen folgender Fehler:

com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception:

** BEGIN NESTED EXCEPTION **

java.io.EOFException

STACKTRACE:

java.io.EOFException
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1963)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2375)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2874)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1623)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1715)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3243)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3172)
at com.mysql.jdbc.Statement.execute(Statement.java:706)
at org.apache.commons.dbcp.DelegatingStatement.execute(DelegatingStatement.java:264)
usw.

** END NESTED EXCEPTION **

Last packet sent to the server was 2 ms ago.
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2586)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2874)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1623)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1715)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3243)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3172)
at com.mysql.jdbc.Statement.execute(Statement.java:706)
at org.apache.commons.dbcp.DelegatingStatement.execute(DelegatingStatement.java:264)

Die folgenden Benutzungen der Connection funktionieren wieder einwandfrei, nur die erste nach dem Timeout nicht.

Wie gehe ich hier am besten vor?
Gibt es bei DBCP so etwas wie auto-Reconnect? Ich habe in der API-Doku nichts dazu gefunden.
 
M

maki

Gast
Ob es dafür einen allgemeine Möglichkeit gibt weiss ich nicht, aber MySQL unterstützt den Autoreconnect, wenn in der Verbindungs URL der Parameter autoreconnect auf true gesetzt wird:

jdbc:mysql:///test?autoReconnect=true...
 

byte

Top Contributor
Hatte mit DBCP ähnliche Probleme in Zusammenhang mit Hibernate. Benutze seitdem C3PO und damit funzt es dank diesem Property:

Code:
c3p0.idle_test_period - Idle time before a c3p0 pooled connection is validated (in seconds)
 

tfa

Top Contributor
Das mit dem autoReconnect-Parameter hab ich auch schon überlegt, aber der ist deprecated.
C3PO ist mir irgendwie zu schwergewichtig. Ich werde mal einen anderen Ansatz mit DBCP versuchen. Vielleicht funktioniert Eviction des BasicDataSource ja.
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen


Oben