2012-09-22 6 views
9

Wenn ich ein Verbindungsobjekt mit DriverManager.getConnection() und , wie unterscheiden sich im Verhalten, wenn .close() für diese Objekte aufgerufen wird?Verbindungsverhalten - DriverManager.getConnection() und DataSource.getConnection()

Vor .close() Methode Aufruf, ich habe relevante Statement und ResultSet Objekte von diesen zwei verschiedenen Verbindungen. Sobald ich diese beiden Objekte bekomme, werde ich, wenn ich connection1.close() (über DriverManager.getConnection()) sage, das Verbindungsobjekt ungültig machen, und ich darf/darf nicht auf die relevanten Statement- und ResultSet-Objekte zugreifen. Korrigiere mich, wenn ich falsch liege?

Zweites Szenario, jetzt, wenn ich sage connection2.close() (über DataSource.getConnection()), es gibt es einfach zurück in den Pool. Aber die Verbindung ist immer noch live. Kann ich auf die zugehörigen Objekte Statement und ResultSet zugreifen?

Antwort

6

Wenn wir eine (grundlegende) DataSource (dh eine, die nicht Verbindungspooling) annehmen, dann erhalten Sie eine physische Verbindung, die die gleiche wie eine von DriverManager erhalten wird (einige Treiber verwenden intern sogar DriverManager von der DataSource oder eine DataSource von DriverManager). Diese Verbindungen werden sich also identisch verhalten.

Wenn nun angenommen wird, dass DataSource Verbindungspooling bereitstellt, verwendet die DataSource selbst ConnectionPoolDataSource (oder einen ähnlichen internen Mechanismus), um PooledConnection zu erhalten. Diese PooledConnection verwaltet die tatsächliche physische Verbindung zur Datenbank. Wenn ein Benutzer eine Verbindung von der DataSource anfordert, prüft die DataSource eine PooledConnection und fragt sie nach einer Connection. Die PooledConnection erstellt dann eine logische Verbindung, die die physische Verbindung verwendet oder umschließt (z. B. über einen Proxy). Die DataSource gibt diese logische Verbindung an den Benutzer zurück.

Für den Benutzer sollte sich die logische Verbindung in allen Aspekten identisch mit einer physikalischen Verbindung verhalten. Wenn also ein Benutzer die Verbindung schließt, werden diese logische Verbindung und alle abhängigen JDBC-Objekte geschlossen und verhalten sich identisch mit einem physischen Verbindungsabschluss.

JDBC 4.1 Abschnitt 11.1 sagt:

Verbindungspooling an den Client vollständig transparent ist: Ein Client erhält eine gepoolte Verbindung und verwendet sie nur die gleiche Art und Weise erhält sie und verwendet eine nicht zusammengefasste Verbindung.

Und Abschnitt 11.4:

Wenn die Anwendung versucht, den logischen Griff wieder zu verwenden, um die Verbindung Implementierung löst eine SQLException.

und

Für ein gegebenes PooledConnection Objekt, nur die zuletzt erzeugte logische Connection-Objekt gültig. Jedes zuvor vorhandene Connection-Objekt wird automatisch geschlossen, wenn die zugehörige PooledConnection.getConnection-Methode aufgerufen wird. jedoch

Im Hintergrund, wenn die logische Verbindung geschlossen ist, wird das PooledConnection der Datasource signalisieren, dass es für die Wiederverwendung zur Verfügung steht, und die Datasource wird es dann an den Verbindungspool zurückzukehren, oder die PooledConnection schließen (das schließt die physische Verbindung), wenn sie die Verbindung nicht mehr benötigt.

Die DataSource kann auch zwangsweise eine Verbindung von einem Benutzer widerrufen (z. B. wenn eine Verbindung zu lange ausgecheckt wird usw.), indem die PooledConnection aufgefordert wird, die logische Verbindung zu schließen.

+0

In meiner Anwendung kann ich auf mein 'ResultSet' Objekt zugreifen, auch nachdem ich mein' Connection' Objekt geschlossen habe. Wie Sie wissen, hat Websphere diese Implementierung nicht bestanden? – Sriram

+0

Das hängt davon ab, was Sie mit Zugriff meinen. Das ResultSet-Objekt wird weiterhin vorhanden sein aber Sie sollten das ResultSet nicht verwenden können, wie es geschlossen sein sollte, wenn die logische Verbindung geschlossen wurde. –

+1

Und wenn es eine falsche Implementierung von WebSphere ist: das hängt davon ab, was Sie als 'ConnectionPoolDataSource' für die' DataSource' von websphere verwenden. Das von mir beschriebene Verhalten sollte durch die Implementierung von 'PooledConnection' erzwungen werden. –

3

connection1.close() (durch DriverManager.getConnection()),

Dies wird die physikalische Verbindung zur Datenbank hergestellt schließen und alle nämlich Ressourcen. Ergebnismenge, Aussage, Verbindung sind freigegeben. Sie können also nicht auf sie zugreifen, nachdem die Verbindung geschlossen wurde.

connection2.close() (durch DataSource.getConnection())

Dies ist Datasource-Implementierung abhängig und so muss das Verhalten in verschiedenen Datasource-Implementierungen nicht konsistent sein. Außerdem hängt der tatsächliche Lebenszyklus einer Verbindung innerhalb einer gegebenen DataSource-Implementierung von verschiedenen anderen Parametern ab, und es wird dringend empfohlen, diese Verbindung nicht von der durch den DriverManager erhaltenen zu unterscheiden.

Wenn Sie wirklich die Daten in den ResultSet verfügbar sein gehalten wollen, nachdem die Statement und Connection geschlossen sind, können Sie einen Blick auf CachedRowSet nehmen, wenn das Ihr usecase paßt.

+2

Logische Verbindungen, die aus einem Verbindungspool stammen, sollten sich (für den Benutzer) genauso verhalten wie physikalische Verbindungen, die vom DriverManager bezogen werden. Für den Benutzer sollten die Verbindung und alle abhängigen Objekte daher geschlossen erscheinen, selbst wenn die physische Verbindung offen bleibt. Wenn sich eine Datenquellenimplementierung anders verhält, entspricht sie nicht der JDBC-Spezifikation. –

3

Das clientseitige Caching hängt möglicherweise davon ab, dass der verwendete Treiber nicht sicher ist. Einige Treiber verhindern jedoch ausdrücklich, dass Sie eine Anweisung oder einen Resultset verwenden, nachdem die Verbindung geschlossen wurde. Andere verwalten das Resultset auf der Client-Seite

Verwandte Themen