Frage

Was ist der beste Weg, um eine Datenbank-Verbindung in einem Java-Servlet zu verwalten?

Zur Zeit öffne ich einfach eine Verbindung in der init() Funktion, und schließen Sie es dann in destroy().

Aber ich bin besorgt, dass „permanent“ auf eine Datenbankverbindung halten könnte eine schlechte Sache sein.

Ist dies der richtige Weg, dies zu umgehen? Wenn nicht, was sind einige besseren Möglichkeiten?

edit: einem bisschen mehr Klarheit zu geben: Ich habe einfach versucht Öffnen / eine neue Verbindung für jede Anforderung zu schließen, aber mit der Prüfung habe ich Leistungsprobleme aufgrund gesehen zu viele Verbindungen zum Erstellen

.

Gibt es einen Wert, der eine Verbindung über mehrere Anforderungen zu teilen? Die Anforderungen für diese Anwendung sind fast alle „read-only“ und kommen ziemlich schnell (obwohl die angeforderten Daten ziemlich klein ist).

War es hilfreich?

Lösung

Ich bin nicht einverstanden tatsächlich mit Commons DBCP verwenden. Sie sollten sich wirklich auf den Behälter verschieben, um das Verbindungsspooling für Sie zu verwalten.

Da Sie Java Servlets verwenden, die in einem Servlet-Container impliziert läuft, und alle wichtigen Servlet Container, die ich vertraut bin mit Connection-Pool-Management bieten (die Java EE-Spezifikation kann es sogar erforderlich). Wenn Ihr Behälter DBCP zu verwenden, geschieht (wie Tomcat der Fall ist), groß, ansonsten nur verwenden, was Ihrem Container bereitstellt.

Andere Tipps

Wie jeder sagt, müssen Sie einen Verbindungspool verwenden. Warum? Was geht? Etc.

Was mit Ihrer Lösung Falsche ist

Ich weiß, das da ich auch dachte, es eine gute Idee, es ist einmal war. Das Problem ist zweifach:

  1. Alle Threads (Servlet-Anfragen mit einem Thread pro jedem bedient wird) werden die gleiche Verbindung teilen. Die Anfragen werden daher einen nach dem anderen verarbeitet bekommen. Dies ist sehr langsam, auch wenn Sie nur in einem einzigen Browser sitzen und lehnen auf der F5-Taste. Versuchen Sie es:. Dieses Zeug klingt auf hohem Niveau und abstrakt, aber es ist empirisch und prüfbar
  2. Wenn die Verbindung bricht aus irgendeinem Grunde wird die init-Methode nicht erneut aufgerufen werden (weil das Servlet wird außer Betrieb nicht genommen werden). Versuchen Sie nicht, dieses Problem zu umgehen, indem ein Try-Catch in der doGet oder doPost setzen, denn dann werden Sie in der Hölle sein (Art eine App-Server zu schreiben ungefragt).
  3. Im Gegensatz zu dem, was man denken könnte, werden Sie keine Probleme mit Transaktionen, da die Transaktion Anfang mit dem Gewinde und nicht nur die Verbindung zugeordnet wird. Ich könnte falsch sein, aber da dies eine schlechte Lösung ist sowieso, nicht schwitzen.

Connection Pool

Verbindungspools geben Sie eine ganze Reihe von Vorteilen, vor allem aber sie lösen die Probleme von

  1. eine echte Datenbank-Verbindung zu machen ist teuer. Der Connection-Pool hat immer ein paar zusätzliche Verbindungen um und gibt Ihnen so eine.
  2. Wenn die Verbindungen ausfallen, weiß der Verbindungspool, wie ein neues zu öffnen
  3. Sehr wichtig: jeder Thread erhält eine eigene Verbindung. Dies bedeutet, dass threading behandelt wird, wo es sein soll: auf der DB-Ebene. DBs sind sehr effizient und gleichzeitige Anforderungen mit Leichtigkeit umgehen kann.
  4. Andere Sachen (wie Standort von JDBC zu zentralisieren verbinden Strings, etc.), aber es gibt Millionen von Artikeln, Bücher etc. zu diesem

Wenn eine Verbindung bekommen

Irgendwo in den Call-Stack in Ihrem Dienst delegieren initiiert (doPost, doGet, doDisco, was auch immer) eine Verbindung erhalten soll, und dann sollten Sie das Richtige tun und bringt sie in einen finally-Block. Ich sollte erwähnen, dass der C # Hauptarchitekt Geck sagte einmal auf eine Zeit, die Sie sollten finally Blöcke 100x mehr als catch Blöcke verwenden. Wahrere Worte nie gesprochen ...

Welche Connection Pool

Sie sind in einem Servlet, so sollten Sie den Verbindungspool verwenden Sie den Behälter zur Verfügung stellt. Ihr JNDI Code wird ganz normal mit Ausnahme, wie Sie die Verbindung erhalten. Soweit ich weiß, haben alle Servlet-Container-Verbindungspools.

Einige der oben genannten Anmerkungen zu den Antworten empfehlen, einen bestimmten Verbindungspool API statt verwenden. Ihre WAR sollte tragbar sein und „nur einzusetzen.“ Ich denke, das im Grunde falsch ist. Wenn Sie den Verbindungspool, der von Ihrem Container bereitgestellt verwenden, wird Ihre App ausfahrbaren auf Container sein, die mehrere Maschinen und all das fancy stuff überspannen, die die Java EE-Spezifikation bietet. Ja, die Container-spezifische Deployment-Deskriptoren müssen geschrieben werden, aber das ist die Art und Weise EE, Mann.

Ein Kommentator erwähnt, dass bestimmte Behälter bereitgestellte Verbindungspools arbeiten nicht mit JDBC-Treiber (er / sie erwähnt Websphere). Das klingt völlig abwegig und lächerlich, so ist es wahrscheinlich wahr. Wenn Sachen wie das passiert, alles werfen du bist „tun sollte“ in den Müll und tun, was Sie können. Das ist, was wir bezahlt haben, manchmal:)

würde ich Commons DBCP verwenden. Es ist ein Apache-Projekt, das den Verbindungspool für Sie verwaltet.

Sie würden nur erhalten Ihre Verbindung in Ihrem doGet oder doPost Ihre Abfrage ausführen, und schließen Sie dann die Verbindung in einem finally-Block. (Con.close () nur gibt es an den Pool, ist es nicht wirklich es schließen).

DBCP kann Verbindungs-Timeouts verwalten und von ihnen erholen. Die Art und Weise Sie derzeit tun Dinge, wenn Ihre Datenbank nach unten für einen beliebigen Zeitraum geht Sie Ihre Anwendung neu zu starten werden.

bündeln Sie Ihre Verbindungen? Wenn nicht, sollten Sie wahrscheinlich den Aufwand der Öffnung reduzieren und Schließen Sie Ihre Verbindungen.

Sobald das aus dem Weg ist, einfach weiter die Verbindung offen, solange es ist notwendig, wie John vorgeschlagen.

Die beste Art und Weise, und ich bin derzeit auf der Suche über Google für eine bessere Referenzblatt ist Pools zu verwenden.

Bei der Initialisierung erstellen Sie einen Pool, X Anzahl der SQL-Verbindungsobjekte zu Ihrer Datenbank enthält. Bewahren Sie diese Objekte in einer Art Liste, wie Arraylist. Jedes dieser Objekte verfügt über eine private boolean für ‚isLeased‘, eine lange für die Zeit, die zuletzt verwendet wurde und eine Verbindung. Jedes Mal, wenn Sie eine Verbindung benötigen, fordern Sie ein aus dem Pool. Der Pool wird entweder geben Sie die erste verfügbare Verbindung, auf der isLeased Variable überprüft, oder es wird eine neue erstellen und es an den Pool. Achten Sie darauf, den Zeitstempel zu setzen. Sobald Sie mit der Verbindung fertig sind, bringen Sie ihn einfach an den Pool, die isLeased auf false gesetzt wird.

Um zu verhindern, ständig mit Verbindungen die Datenbank binden, können Sie einen Worker-Thread erstellen, die gelegentlich durch den Pool gehen und sehen, wann das letzte Mal eine Verbindung verwendet wurde. Wenn es lange genug hat, kann er diese Verbindung schließen und aus dem Pool entfernen.

Die Vorteile dieses zu verwenden, ist, dass Sie nicht haben Sie warten lange Wartezeiten für ein Connection-Objekt in der Datenbank zu verbinden. Ihre bereits bestehenden Verbindungen können so viel wiederverwendet werden, wie Sie möchten. Und Sie werden die Anzahl der Verbindungen festlegen, um basierend darauf, wie beschäftigt Sie Ihre Anwendung denken sein wird.

Sie sollten nur eine Datenbankverbindung für so lange offen halten, wie Sie es brauchen, was davon abhängt, was Sie tun wahrscheinlich im Rahmen Ihrer doGet/doPost Methoden ist.

Pool es.

Auch wenn Sie roh JDBC tun, Sie in etwas aussehen könnten, dass Sie die Verbindung verwalten kann, PreparedStatement usw. Es sei denn, Sie sehr tight „Leichtgewichtigkeit“ Anforderungen haben, Spring JDBC-Unterstützung unter Verwendung von, zum Beispiel, wird zur Vereinfachung Ihr Code ein Los- und Sie keinen anderen Teil des Frühlings zu verwenden gezwungen.

einige Beispiele Siehe hier:

http://static.springframework.org/spring /docs/2.5.x/reference/jdbc.html

Ein Verbindungspool mit einer Datenquelle verbunden ist, soll den Trick. Sie können halten die Verbindung von der Datenquelle in der Servlet-Request-Methode erhalten (doget / dopost, etc).

dbcp, c3p0 und viele andere Verbindungspools können tun, was Sie suchen. Während Sie Verbindungen sind bündeln, können Sie Anweisungen und PreparedStatements zu bündeln; Auch, wenn Sie ein READ HEAVY Umgebung sind, wie Sie angegeben, möchten Sie vielleicht einige der Ergebnisse mit so etwas wie ehcache zwischenzuspeichern.

BR,
~ A

In der Regel werden Sie feststellen, dass Verbindungen pro Anfrage Öffnen ist einfacher zu verwalten. Das bedeutet, dass in der doPost () oder die doGet () -Methode des Servlets.

Öffnen in der init () macht es auf alle Anfragen zur Verfügung und was passiert, wenn Sie gleichzeitige Anforderungen haben?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top