Ist die Verwendung von PreparedStatements in einem Thread in Java korrekt?

7

Ich bin immer noch ein Student, der nur Teilzeit arbeitet, und so versuche ich immer, mir bessere Möglichkeiten zu merken, Dinge zu tun. Kürzlich musste ich ein Programm für Arbeit schreiben, wo der Hauptthread des Programms "Aufgaben" -Threads (für jeden db- "Aufgaben" -Datensatz) erzeugen würde, die einige Operationen ausführen würden und dann den Datensatz aktualisieren würden, um zu sagen, dass er beendet wurde. Daher benötigte ich ein Datenbankverbindungsobjekt und PreparedStatement-Objekte in den ThreadedTask-Objekten oder diesen verfügbar.

Dies ist ungefähr das, was ich am Ende geschrieben habe, ist die Erstellung eines PreparedStatement -Objekts pro Thread eine Verschwendung? Ich dachte, statische PreparedStatments könnte Race Conditions erstellen ...

%Vor%

A's Version wird nie ausgeführt ..

Ist dieser Thread sicher? Erzeugt und zerstört PreparedStatement Objekte, die immer gleich sind, keine große Verschwendung?

%Vor%     
ArturPhilibin 26.04.2010, 12:31
quelle

3 Antworten

16

Ich glaube, es ist keine gute Idee, Datenbankverbindungen (und vorbereitete Anweisungen) zwischen Threads freizugeben. JDBC erfordert keine Verbindungen thread-safe, und ich würde erwarten, dass die meisten Treiber nicht sein.

Geben Sie jedem Thread eine eigene Verbindung (oder synchronisieren Sie die Verbindung für jede Abfrage, was aber wahrscheinlich den Zweck, mehrere Threads zu haben, zunichte macht).

  

Erzeugt und zerstört PreparedStatement Objekte, die immer gleich sind, keine große Verschwendung?

Nicht wirklich. Der Großteil der Arbeit findet auf dem Server statt und wird dort zwischengespeichert und wiederverwendet, wenn Sie dieselbe SQL-Anweisung verwenden. Einige JDBC-Treiber unterstützen auch das Zwischenspeichern von Anweisungen, sodass auch das clientseitige Kontoauszugs-Handle wiederverwendet werden kann.

Sie können eine wesentliche Verbesserung sehen, wenn Sie statt (oder zusätzlich zu) mehreren Threads Batch-Abfragen verwenden. Bereiten Sie die Abfrage einmal vor und führen Sie sie für viele Daten in einem großen Batch aus.

    
Thilo 26.04.2010, 12:34
quelle
6

Die Threadsicherheit ist hier nicht das Problem. Alles sieht syntaktisch und funktionell gut aus und sollte etwa eine halbe Stunde funktionieren. Der Verlust von Ressourcen ist jedoch das eigentliche Problem. Die Anwendung wird nach etwa einer halben Stunde abstürzen, weil Sie sie nie nach der Verwendung schließen. Die Datenbank wird früher oder später die Verbindung selbst schließen, damit sie sie zurückerhalten kann.

Das heißt, Sie müssen sich keine Gedanken über die Zwischenspeicherung von vorbereiteten Anweisungen machen. Der JDBC-Treiber und die DB werden sich um diese Aufgabe kümmern. Sorgen Sie sich eher um Ressourcenverlust und machen Sie Ihren JDBC-Code so solide wie möglich.

%Vor%

Um die Verbindungsleistung zu verbessern, verwenden Sie einen Verbindungspool wie c3p0 (dies bedeutet übrigens nicht, dass Sie das können Ändern Sie die Art und Weise, wie Sie den JDBC-Code schreiben, immer und schließen Sie die Ressourcen im kürzestmöglichen Bereich in einem try-finally -Block).

    
BalusC 26.04.2010 12:46
quelle
3

Verwenden Sie am besten einen Verbindungspool und fordern Sie jeden Thread dazu auf, eine Verbindung aus dem Pool anzufordern. Erstellen Sie Ihre Aussagen zu der Verbindung, die Sie übergeben haben, und vergessen Sie nicht, sie zu schließen. Geben Sie sie dann wieder in den Pool zurück, wenn Sie fertig sind. Der Vorteil der Verwendung des Pools besteht darin, dass Sie die Anzahl der verfügbaren Verbindungen leicht erhöhen können, wenn Sie feststellen, dass die Thread-Parallelität zu einem Problem wird.

    
Trevor Tippins 26.04.2010 12:37
quelle