JDBC grundlegende Konzepte, Pooling und Threading

7

Ich habe JDBC in JavaSE immer in einer Single-Thread-Umgebung verwendet. Aber jetzt muss ich einen Verbindungspool verwenden und viele Threads mit der Datenbank interagieren lassen (MSSQL und Oracle) und es fällt mir schwer, es zu versuchen, da es mir an fundamentaler Unerschütterlichkeit der API mangelt / p>

AFAIK nach dem Verbinden und Protokollieren von Connection stellt eine physische tcp / ip-Verbindung zur Datenbank dar. Es erstellt Statement (s), die als SQL-Interaktion (en) mit der Datenbank über Connection betrachtet werden können.

  • Wo kommt die Transaktion und das Rollback zustande? Ist es auf der Ebene Connection oder Statement .
  • Ist es sicher, dass 'one' Connection N Anweisungen erstellt und sie an verschiedene Threads weitergibt, damit jeder die Statement benutzen kann?

Wenn nicht, und nach dem Konfigurieren des Pools etwa so:

%Vor%
  • BTW, wo stelle ich die Größe des Verbindungspools ein?

  • Würde ich das in jedem Thread tun, um die Verbindung korrekt zu nutzen?

// thead run-Methode

%Vor%

// Ende der Thread-Laufmethode

  • Wenn eine physische Verbindung des Pools irgendwie abstürzt oder nicht mehr funktioniert, wird der Pool automatisch versuchen, die neue Verbindung im Pool wiederherzustellen und zu injizieren, so dass die nachfolgende pool.getConnection () nur eine Verbindung erhält?

Vielen Dank und verzeih mir mein schlechtes Englisch.

    
David Hofmann 13.08.2009, 14:56
quelle

7 Antworten

6

Verbindungspools dekorieren Connection- und Statement-Instanzen mit eigenen Wrapper-Implementierungen. Wenn Sie eine Verbindung schließen, geben Sie sie gerade zurück in den Pool. Wenn Sie eine vorbereitete Anweisung schließen, geben Sie sie gerade wieder in den Anweisungscache der Verbindung zurück. Wenn Sie eine Anweisung vorbereiten, holen Sie möglicherweise nur eine zwischengespeicherte Anweisungsinstanz aus der Verbindung ab. All dies ist nicht sichtbar, so dass Sie sich keine Sorgen machen müssen.

Wenn eine Verbindung zu einem Client hergestellt wird, steht sie keinem anderen Client mehr zur Verfügung, bis die Verbindung zum Pool freigegeben wird. Im Allgemeinen rufen Sie nur Verbindungen ab, wenn Sie sie benötigen, und geben sie dann zurück, sobald Sie mit ihnen fertig sind. Da die Verbindungen im Pool offen gehalten werden, ist der Aufwand beim Abrufen und Freigeben von Verbindungen gering.

Sie sollten eine Verbindung aus dem Pool genauso wie eine einzelne JBDC-Verbindung verwenden und die Best Practices für das Schließen von Ressourcen befolgen, damit keine Verbindungen oder Anweisungen verloren gehen. Sehen Sie sich die Beispiele try / catch / finally in einigen anderen Antworten an.

Pools können die Verbindungsressourcen verwalten und sie testen, bevor sie an Clients verteilt werden, um sicherzustellen, dass sie nicht veraltet sind. Ein Pool erstellt und zerstört Verbindungen nach Bedarf.

    
teabot 13.08.2009, 20:19
quelle
7

Wenn Sie JDBC mit Single-Threading beherrschen, sollten Sie keine Multi-Threading- und Verbindungspools verwenden. Alles, was Sie anders machen müssen, ist: 1. Wenn Sie eine Verbindung benötigen, holen Sie sie aus dem Pool statt direkt. 2. Jeder Thread sollte seine eigenen Verbindungen bekommen.

Um Punkt 2 zu verdeutlichen: Wenn Sie eine Verbindung erhalten und sie dann an mehrere Threads übergeben, könnten Sie zwei Threads haben, die versuchen, Abfragen für dieselbe Verbindung gleichzeitig auszuführen. Java wird Ausnahmen davon auslösen. Sie können nur eine aktive Anweisung pro Verbindung und eine aktive Abfrage (d. H. ResultSet) pro Anweisung haben. Wenn zwei Threads das gleiche Connection-Objekt enthalten, verletzen sie diese Regel wahrscheinlich sofort.

Eine weitere Einschränkung: Achten Sie beim Verbindungs-Pooling darauf, Ihre Verbindungen immer zu schließen, wenn Sie fertig sind. Der Pool-Manager hat keine definitive Möglichkeit zu wissen, wann Sie eine Verbindung fertig haben. Wenn Sie also keine Verbindung herstellen können, wird es lange Zeit dort hängen bleiben, möglicherweise für immer, abhängig vom Pool-Manager. Ich folge immer immer jeder "getConnection" mit einem try-Block und schließe die Verbindung im finally-Block. Dann weiß ich, dass ich es geschlossen habe, bevor die Funktion beendet wird.

Außerdem sollte alles so sein, wie Sie es gewohnt sind.

    
Jay 13.08.2009 17:01
quelle
3
  1. Transaktionen finden auf der Verbindungsebene statt.

  2. Nein. Normalerweise stellt der JDBC-Treiber sicher, dass Sie keine zweite Anweisung über dieselbe Verbindung ausführen können, während eine andere aktiv ist.

Wenn Sie Verbindungspooling benötigen, versuchen Sie das DBCP-Framework . Es bietet ziemlich anständige Fehlerbehandlung (wie veraltete Verbindungen und Verbindungen, die vom Client-Code nicht zurückgegeben wurden).

Wie für Ihren Code: Umschließen Sie den Code immer in try{...}finally{...} :

%Vor%

Dieser Code stellt sicher, dass alle Verbindungen usw. immer korrekt geschlossen sind und dass jede Ausnahme beim Schließen keinen vorherigen Fehler verdeckt.

    
Aaron Digulla 13.08.2009 14:58
quelle
2

Ich denke, Sie sollten mit dem Sun Tutorial zum Verbindungs-Pooling beginnen. Darüber hinaus gibt es viele Implementierungen von Verbindungspooling, einige Open Source, einschließlich eines von Apache . Sie sollten wirklich dort anfangen, anstatt das Rad hier neu zu erfinden.

    
Yishai 13.08.2009 15:02
quelle
1

Sie können nur eine Anweisung für eine bestimmte Verbindung geöffnet lassen. Das Erstellen von mehr als einer Verbindung über einen Verbindungspool ist nicht so schwierig, obwohl die beste Möglichkeit darin besteht, eine der größeren Verbindungen dort zu verwenden.

Wenn Sie den Standard-JDBC-Standard verwenden, empfehle ich PreparedStatement over Statement.

Ich habe iBatis benutzt und es ist ziemlich nett. Bringt noch ein paar andere Dinge auf den Tisch.

    
Nick 13.08.2009 15:04
quelle
0

Werfen Sie einen Blick auf dieses (+:

    
Everyone 13.08.2009 15:27
quelle
0

Zusätzliche Bits:

  1. Anwendungsserver neigen dazu, Verbindungspooling bereitzustellen, und es kann ziemlich clever werden. Wenn Sie einen App-Server verwenden, untersuchen Sie sorgfältig, was Sie auspacken, bevor Sie etwas Eigenes hinzufügen.

  2. Transaktionen: wenn Sie

    haben

    Beginne die Transaktion

    Verbindung erhalten  Arbeit  close connection // bedeutet Rückkehr zum Pool

    Verbindung herstellen (mit gleicher Isolationsstufe usw.)
             // Sie erhalten eine SAME Verbindung, der Pool reserviert sie für Ihre Transaktion

    Arbeit // passiert in der gleichen Transaction  Verbindung schließen

    Commit-Transaktion // schreibt die gesamte Arbeit fest

  3. Verbindungen und Fehler

Poolimplementierungen können schlau sein. Wenn bei einer Verbindung aus dem Pool bestimmte Fehler auftreten, die darauf hinweisen, dass der DB-Server zurückgewiesen wurde, kann der Pool auswählen, alle Pool-Mitglieder zu verwerfen.

    
djna 13.08.2009 15:33
quelle