MySQL Design-Problem: DB-Verbindung herstellen und halten - JdbcRowSet / Idle-Timeout?

jeppi

Mitglied
Hallöle,

ich bin am Ende meines Lateins, und im Web finde ich einfach nichts vernünftiges zu dem Thema, selbst in ansonsten guten Tutorials schweigt sich anscheinend alle Welt zu diesem Thema aus:

Zuerst habe ich den mysql-connector verwendet, mittlerweile bin ich auf JdbcRowSet umgestiegen. Die Problematik bleibt aber immer die gleiche:

Meine Datenbank im Web scheint mich immer nach einer Weile nichtstun zu disconnecten (was von Seiten des Anbieters auch verständlich ist). Nur weiss ich nicht, wie ich von Java-Seite damit umgehen soll, wenn mir der Server die verbindung unter dem Hintern wegzieht. Mit einer lokalen Datenbank (localhost oder zweiter linux-pc) hatte ich die probleme nicht.

Um beim Beispiel JdbcRowSet zu bleiben, hier meine prinzipielle Vorgehensweise:

Java:
JdbcRowSet jdbcRs = new JdbcRowSetImpl();
jdbcRs.setUsername(user);
jdbcRs.setPassword(pw);
jdbcRs.setUrl(url);

String sql = "SELECT name, wert FROM table";
jdbcRs.setCommand(sql);
jdbcRs.execute();
jdbcRs.next();
[...]

// mit dem Ergebnis wird jetzt gearbeitet
//
// jetzt vergeht mitunter viel zeit (mitunter viele Minuten), 
// weil ein Kunde kommt oder so

[...]
jdbcRs.updateString("wert", "neue änderung");
jdbcRs.update(Row);

Wie gehe ich mit diesem Problem um? das dürfte ja wohl ein idle-Timeout sein, da es nach längerer Untätigkeit auftritt. Die Fehlermessage ist im wesentlichen:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 571.297 milliseconds ago. The last packet sent successfully to the server was 16 milliseconds ago.
[...]
Caused by: java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.


Ich denke, ich habe es hier mit einem prinzipiellen Design-Fehler meinerseits zu tun. Wenn nun jemand einen guten Rat hat oder ein Tutorial kennt, wie ich solche Timeouts vermeide bzw. trotz derer eine Datenbankanbindung stabil und zuverlässig hinbekomme, wäre ich sehr dankbar.

Ich habe mir schon mehrere Tage einen Wolf gegoogelt und bin wirklich am Ende... :rtfm: 😕
 
Ich würde da einen Connection-Pool verwenden, der kümmert sich um das Reconnect und ist DB-unabhängig. Allerdings hab ich keine Ahnung wie das mit JdbcRowSet funktioniert.
 
Probiere im Connectionstring den UrlParameter "autoreconnect=true". Damit könnte das Problem gelöst sein. 🙂

Ist meiner Meinung nach nicht zu empfehlen. Man hat zwar eine Verbindung offen, aber die frisst Ressourcen und das muss ja beim Nichtstun nicht sein. Sprich da mach es lieber wie tfa es gesagt hat und verwende einen Verbindungspool. Dann nimmst dir bei jeder Anfrage eines Browser eine eigene Verbindung, die du nach gleich wieder zumachen kannst, wenn die Anfrage abgearbeitet ist und die Response auf die Reise geschickt wird.
 
Probiere im Connectionstring den UrlParameter "autoreconnect=true". Damit könnte das Problem gelöst sein. 🙂

Beim jdbcRowSet funktioniert das so zumindest nicht, mir fliegt die Verbindung nachwievor um die Ohren. Aber immerhin weiß ich jetzt, dass es soeine Option gibt. Bin ich noch nirgendwo drüber gestolpert... insofern Danke, auch wenn's nicht hilft. 😉
 
Ich würde da einen Connection-Pool verwenden, der kümmert sich um das Reconnect und ist DB-unabhängig. Allerdings hab ich keine Ahnung wie das mit JdbcRowSet funktioniert.

Hm... habe ich mich noch nie mit beschäftigt.
Setzt sowas auf den Connector auf?

... muss ich mich wohl mal schlau machen... interessanter Tipp - danke.
 
Man hat zwar eine Verbindung offen, aber die frisst Ressourcen und das muss ja beim Nichtstun nicht sein.

Das wäre aber hier nicht das Problem. Da wären wenn's wirklich hoch kommt in Praxis drei PCs mit einer "stehenden" Verbindung zur DB. Nur funktioniert es mit dem jdbcrowset anscheinend nicht.

Wenn das jdbcRowSet die Verbindung übernimmt, hat man auch anscheinend auch keine echte Kontrolle mehr darüber. Also werde ich da doch lieber eine Connection übergeben, über die ich dann auch eine Gewisse Kontrolle ausüben kann.

Dann werde ich immer brav vor jedem Schritt die Verbindung herstellen, dann Schritt durchführen, dann Verbindung kappen... da bekommt das java dann was zu tun - und ich auch die nächsten Abende :applaus:
 
Das setzt idR auf JDBC auf.

Yeah, that's it! danke! 🙂

Genau das dürfte mein Problem sein: Verschiedene Clients scheinen sich bei mir gegenseitig ins Gehege zu kommen....

Der dpunkt hat zum oracle-Treiber was geschrieben, aus dem das dahinterliegende Prinzip gut deutlich wird (naja, wenn man schon etwas tiefer in der Materie drinsteckt, jedenfalls):

Connection Pooling :rtfm:

edit: Wenn ich weitergekommen bin, dann melde ich mich hier wieder...
 
Langsam versteh ich, wie der Hase rennt.

Meine größter Fehler war das Nutzen einer einzelnen Connection für verschiedene Resultsets in verschiedenen Paketen, bei denen sich die Nutzung der einen Connection gegenseitig überschnitten hat 😳

Zuerst habe ich die Abfragen atomisiert und bei der Gelegenheit das exception-handling verbessert

1.) connect
2.) Abfrage mit JdbcRowSet
3.) close des RowSets
4.) close der Connection

Die Datenbankabfrage wurde dadurch zwar echt lahm, weil das Programm ständig Verbindungen zur DB öffnete und schloss, aber...

...dann habe ich DBCP integriert. Eine simple pooled connection kam nicht infrage, weil sich zwei Abfragen nachwievor überschneiden (voneinander abhängig).

Nun werkelt das Programm recht stabil mit zwei Connections vor sich hin, um die ich mich nicht kümmern muss. :toll:

Danke an tfa & DerEisteeTrinker !
 

Zurück
Oben