2008-11-14 7 views
5

Es scheint, als ob die klassische Methode, Transaktionen mit JDBC zu verarbeiten, darin besteht, Auto-Commit auf false zu setzen. Dies erstellt eine neue Transaktion, und jeder Aufruf zum Festschreiben markiert den Beginn der nächsten Transaktionen. In Multithreading-Anwendung verstehe ich, dass es üblich ist, eine neue Verbindung für jeden Thread zu öffnen.JDBC: Kann ich eine Verbindung in einer Multithreading-App teilen und nette Transaktionen genießen?

Ich schreibe eine RMI-basierte Multi-Client-Server-Anwendung, so dass im Grunde mein Server nahtlos einen Thread für jede neue Verbindung erstellt. Um Transaktionen richtig zu behandeln, sollte ich gehen und eine neue Verbindung für jeden dieser Thread erstellen? Sind die Kosten für eine solche Architektur nicht unerschwinglich?

Antwort

4

Ja, im Allgemeinen müssen Sie für jeden Thread eine neue Verbindung erstellen. Sie haben keine Kontrolle darüber, wie das Betriebssystem die Ausführung von Threads verzögert (ungeachtet der Definition Ihrer eigenen kritischen Abschnitte), sodass Sie versehentlich mehrere Threads verwenden könnten, die versuchen, Daten über diese eine Pipe zu senden.

Beachten Sie das Gleiche gilt für jede Netzwerkkommunikation. Wenn Sie beispielsweise zwei Threads hatten, die versuchten, einen Socket mit einer HTTP-Verbindung zu teilen.

  • Thread 1 stellt eine Anfrage
  • Thread 2 eine Anforderung
  • Thread 1 liest Bytes aus der Steckdose, ohne es zu wissen die Antwort vom Wunsch des Gewindes 2 Lesen

Wenn Sie alle Ihre Transaktionen eingewickelt In kritischen Abschnitten sperren Sie daher alle anderen Threads für einen gesamten Begin/Commit-Zyklus. Dann können Sie möglicherweise eine Datenbankverbindung zwischen Threads freigeben. Aber ich würde das auch dann nicht tun, wenn Sie nicht wirklich das JDBC-Protokoll beherrschen.

Wenn die meisten Ihrer Threads nur selten Datenbankverbindungen benötigen (oder gar nicht), können Sie möglicherweise einen Thread für Ihre Datenbankarbeit festlegen und andere Threads ihre Anforderungen an diesen einen Thread in Warteschlange stellen lassen. Das würde den Overhead von so vielen Verbindungen reduzieren. Aber Sie müssen herausfinden, wie Sie Verbindungen pro Thread in Ihrer Umgebung verwalten (oder stellen Sie eine andere spezifische Frage dazu in StackOverflow).

update: Um Ihre Frage in dem Kommentar zu beantworten, unterstützen die meisten Datenbankmarken nicht mehrere gleichzeitige Transaktionen auf einer einzigen Verbindung (InterBase/Firebird ist die einzige Ausnahme, die ich kenne).

Es wäre nett, ein separates Transaktionsobjekt zu haben und mehrere Transaktionen pro Verbindung zu starten und zu committen. Aber Verkäufer unterstützen es einfach nicht.

Ebenso machen herstellerunabhängige APIs wie JDBC und ODBC die gleiche Annahme, dass der Transaktionszustand lediglich eine Eigenschaft des Verbindungsobjekts ist.

+0

Ok ... Nur aus Neugier, haben Sie eine Vorstellung davon, warum die Definition der Transaktion mit der Definition der Verbindung auf JDBC verbunden ist? Ich würde ein Transaktionsobjekt wirklich schätzen. – fulmicoton

+0

Vielen Dank für Ihre Antwort !!! – fulmicoton

+1

Die Aussage "Sie könnten unbeabsichtigt mehrere Threads haben, die versuchen, Daten nach unten zu schicken" in dieser Antwort ist definitiv falsch für postgresql. Siehe http://doc.postgresintl.com/jdbc/ch10.html. Die Verbindung ist zumindest Thread-sicher, wenn auch nicht vollständig parallelisiert, wie es sein könnte. –

1

Es ist unüblich, für jeden Thread eine neue Verbindung zu öffnen. Normalerweise verwenden Sie einen Verbindungspool wie c3po Bibliothek.

Wenn Sie sich auf einem Anwendungsserver befinden oder beispielsweise Hibernate verwenden, sehen Sie in der Dokumentation nach und erfahren Sie, wie Sie den Verbindungspool konfigurieren.

+0

Vielen Dank für Ihren Beitrag. Ich sollte in Ordnung sein ohne einen Verbindungspool in meinem Fall: Ich werde wahrscheinlich nicht allzu oft nach Verbindungen fragen. Für andere Leser: Ich bin mir ziemlich sicher, dass c3po eine großartige Bibliothek ist, aber stellen Sie sicher, dass es in Ordnung ist, dass Sie LGPL verwenden. – fulmicoton

+0

Was ist das Problem mit der LGPL? Sie können es mit kommerziellen Anwendungen verwenden (es ist Lesser GPL). –

1

Das gleiche Verbindungsobjekt kann zum Erstellen mehrerer Anweisungsobjekte verwendet werden, und diese Anweisungsobjekte können dann von verschiedenen Threads gleichzeitig verwendet werden.Die meisten modernen DBs, die mit JDBC verbunden sind, können das tun. Die JDBC kann daher die folgenden Cursor wie folgt verwenden. PostgreSQL ist hier keine Ausnahme, siehe zum Beispiel:

http://doc.postgresintl.com/jdbc/ch10.html

Dies ermöglicht Connection Pooling, wo die Verbindung nur für eine kurze Zeit verwendet wird, nämlich um die Anweisung Objekt erstellt und aber danach wieder in den Pool. Dieses Kurzzeit-Pooling wird nur empfohlen, wenn die JDBC-Verbindung auch die Anweisungsoperationen parallelisiert, da sonst das normale Verbindungs-Pooling bessere Ergebnisse zeigt. Jedenfalls kann der Thread mit dem Anweisungsobjekt weiterarbeiten und später schließen, nicht aber die Verbindung.

1. Thread 1 opens statement 
3. Thread 2 opens statement 
4. Thread 1 does something   Thread 2 does something 
5. ...        ... 
6. Thread 1 closes statement  ... 
           7. Thread 2 closes statement 

Das obige funktioniert nur im Auto Commit-Modus. Wenn Transaktionen benötigt werden, muss die Transaktion nicht an einen Thread gebunden werden. Sie können das Pooling nur entlang der Transaktionen partitionieren und den gleichen Ansatz wie oben verwenden. Dies ist jedoch nur wegen einer Socket-Verbindungsbeschränkung nicht erforderlich, sondern weil die JDBC dann die Sitzungs-ID mit der Transaktions-ID gleichsetzt.

Wenn ich mich gut erinnere, sollte es APIs und Produkte mit einem weniger vereinfachten Design geben, wobei die Sitzungs-ID und die Transaktions-ID nicht gleichgesetzt werden. In diesen APIs könnten Sie Ihren Server mit einem einzigen Datenbankverbindungsobjekt schreiben, selbst wenn es Transaktionen tut. Sie müssen später überprüfen, was diese APIs und Produkte sind.