Connection Pool: "Timeout waiting for idle object" Exception

oetzi

Bekanntes Mitglied
Hallo zusammen,

hab ein Problem mit einem Connection Pool, der vom Tomcat verwaltet wird.
Eigentlich ist ein Connection Pool ja eine simple Sache, bei der man nicht sooo viel falsch machen kann. Dachte ich jedenfalls bis vor kurzem... ;-)

Das eigentlich Problem ist folgendes:
- Ich starte den Tomcat
- Kann eine recht kurze Zeit normal die Anwendung nutzen (10-30 Minuten)
- Dann fliegen auf einmal "Timeout waiting for idle object" Exeptions

Folgende Eckdaten sind wohl noch relevant:
- In der MySQL Datenbank selbst als auch im Tomcat habe ich die max. Verbindungen auf 500 gesetzt habe (was ja schon weit über jeder Beispielkonfig in den verschiedenen Tutorials liegt)
- Ich mache in jeder Datenbankklasse im final Block ein con.close() -> Nach meinem Verständnis müsste an dieser Stelle doch die Verbindung zurück an den Connection Pool gehen
- Selbst wenn ich eine halbe Stunde warte, nachdem die Exceptions fliegen, besteht das Problem weiterhin. Vorallem dieser Punkt macht mich stutzig. Es scheint ja so, als würden die Verbindungen nie an den Pool zurück gehen. Ich kann mir nur überhaupt nicht erklären warum das so ist.

Hat hier vielleicht schon jemand eine grundsätzliche Idee, was solch ein Problem hervorrufen kann?


Die letzte Idee, die ich noch habe ist, dass es vielleicht an der Art und Weise liegt, wie ich den Connection Pool in meiner Webanwendung handhabe.
Aktuell sieht mein Code so aus:

Beim Start des Servers wird in einem Servlet der ConPool initiiert
Code:
Context initContext = new InitialContext();
Context envContext  = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("jdbc/conPool");

//und im servletContext gespeichert
ServletContext context = getServletContext();
context.setAttribute("conPool", ds);

In meinen Datenbankklassen holen ich die Datasource dann wie folgt (es handelt sich um eine struts2 Anwendung, darum der ActionContext)
Code:
ActionContext context = ActionContext.getContext();
Map<String,Object> appCon = context.getApplication();
ds = (DataSource) appCon.get("conPool");  
con = ds.getConnection();
return con;
}

Kann hier irgendwo was falsch laufen, bzw. irgendwas so laufen, dass der conPool die Verbindungen nicht zurück erhält?

Schönen Gruß,
oetzi
 
Zuletzt bearbeitet:

oetzi

Bekanntes Mitglied
Ich glaube ich habe gerade einen wichtigen Punkte entdeckt!
Ich hatte nach einer Möglichkeit gesucht den Connection Pool zu monitoren. Bis jetzt wusste ich nie, was wirklich unter der Haube abläuft. Mit VisualVM funktioniert das sehr gut!

Dabei habe ich jetzt folgendes entdeckt.
Die numActive Zahl steigt und steigt je länger ich die Anwendung nutze und scheint nie zu fallen. (Allerdings war man "längster" Test jetzt vielleicht 5 Minuten). In dem Moment wenn die numActive den maxActive Wert erreicht hat fliegen die Exceptions!

Mir persönlich bringt das leider erst mal nicht viel, da mir das Hintergrundwissen fehlt um mir ausmalen zu können, warum die numActive nicht mehr runter gehen. Laut google sollten sie das jedenfalls :)

Ich hoffe jetzt wo es langsam etwas konkreter hat jemand einen heißen Tipp für mich :)
 

Anhänge

  • monitoring.png
    monitoring.png
    18,4 KB · Aufrufe: 42

Effad

Mitglied
Java:
ActionContext context = ActionContext.getContext();
Map<String,Object> appCon = context.getApplication();
ds = (DataSource) appCon.get("conPool");  
con = ds.getConnection();
return con;
}
Die Klasse, wo der Code vorkommt und eine Verwendung mit .close() Aufruf.
Da ist irgendwas schief ;-).

Poste mal mehr Code.
 

oetzi

Bekanntes Mitglied
Hallo Effad,

hatte leider deine Antwort nicht direkt gesehen, da ich nicht mehr jeden Tag reingeguckt hatte.
Ich habe das Problem jetzt diese Woche gelöst gekriegt!! Man glaubt es kaum :)

Wie so oft ist es im Nachhinein eine kleinere, dumme Sache gewesen...

In meinen Datenbankklassen hatte ich als Klassenattribute ein einziges Connection Objekt definiert, welches von allen Datenbankmethoden verwendet worden ist.
Jetzt hat sich Methode A eine Verbindung geholt und in diesem Connection Objekt gespeichert. Innerhalb der gleichen Methode wurde Methode B aufgerufen, welche sich wiederrum eine Connection geholt hat und diese wieder auf das gleiche Connection Objekt gelegt hat. Somit wurde dann zwar die Connection von Methode B korrekt geschlossen, anschließend konnte Methode A aber die Verbindung nicht mehr schließen, da diese im digitalen Nirvana verschwunden war.

Jetzt habe ich einfach in jeder Methode ein eigenen Connection Objekt und das Problem ist voll und ganz gelöst! Keine einzige numActiv Verbindung mehr, nachdem die Verarbeitung abgeschlossen ist.

Schon ärgerlich, wie lange ich mich damit beschäftigt habe!

Schönes Wochenende!
oetzi
 

Ähnliche Java Themen

Neue Themen


Oben