2012-09-22 11 views
9

Se ho un oggetto di connessione utilizzando DriverManager.getConnection() e DataSource.getConnection(), come essi differiscono nel comportamento quando .close() viene chiamato su quegli oggetti?comportamento Connection - DriverManager.getConnection() e DataSource.getConnection()

Prima della chiamata al metodo .close(), ho ottenuto gli oggetti Statement e ResultSet rilevanti da queste due connessioni diverse. Subito dopo aver ottenuto questi due oggetti, se dico connection1.close() (tramite DriverManager.getConnection()), si annulla l'oggetto di connessione e non si suppone/si possa accedere agli oggetti Statement e ResultSet rilevanti. Correggimi se sbaglio?

Secondo scenario, ora se dico connection2.close() (tramite DataSource.getConnection()), lo restituisce semplicemente alla piscina. Ma la connessione è ancora attiva. Potrò accedere agli oggetti Statement e ResultSet associati?

risposta

6

Se si presuppone un (base) DataSource (ovvero: uno che non esegue il pool di connessioni), si ottiene una connessione fisica uguale a quella ottenuta da DriverManager (alcuni i driver utilizzano internamente DriverManager da DataSource o DataSource da DriverManager). Quindi quelle connessioni si comportano in modo identico.

Ora se assumiamo un DataSource che fornisce il pool di connessioni, quindi il DataSource si utilizza un ConnectionPoolDataSource (o un meccanismo interno simile) per ottenere un PooledConnection. PooledConnection gestisce la connessione fisica effettiva al database.

Quando un utente richiede una connessione da DataSource, DataSource eseguirà il checkout di PooledConnection e chiederà uno Connection. PooledConnection creerà quindi una connessione logica che utilizza o avvolge la connessione fisica (ad esempio utilizzando un proxy). DataSource restituirà tale connessione logica all'utente.

Per l'utente la connessione logica deve comportarsi in modo identico a una connessione fisica in tutti gli aspetti. Pertanto, quando un utente chiude la connessione, quella connessione logica e tutti gli oggetti JDBC dipendenti verranno chiusi e si comportano in modo identico a una chiusura fisica.

JDBC 4.1 sezione 11.1 dice:

Il pool di connessioni è completamente trasparente per il cliente: un client ottiene un pool collegamento e lo utilizza allo stesso modo si ottiene e utilizza una connessione non in pool.

e la sezione 11.4:

Se l'applicazione tenta di riutilizzare il manico logica, l'attuazione di collegamento tiri uno SQLException.

e

Per un determinato oggetto PooledConnection, solo l'oggetto di collegamento logico di recente ha prodotto sarà valido. Qualsiasi oggetto Connection precedentemente esistente viene automaticamente chiuso quando viene chiamato il metodo PooledConnection.getConnection associato.

Nei precedenti tuttavia, quando la connessione logica è chiuso, l'PooledConnection segnalerà il DataSource che è disponibile per il riutilizzo, e il DataSource poi restituirlo al pool di connessioni, o chiudere il PooledConnection (che chiude la connessione fisica) se non ha più bisogno della connessione.

DataSource può anche forzatamente revocare una connessione da un utente (ad esempio quando una connessione viene controllata troppo a lungo, ecc.), Chiedendo a PooledConnection di chiudere la connessione logica.

+0

Nella mia applicazione, sono in grado di accedere al mio oggetto 'ResultSet' anche dopo aver chiuso il mio oggetto' Connection'. Quindi, secondo te, Websphere ha fallito questa implementazione? – Sriram

+0

Dipende da cosa intendi con accesso. L'oggetto ResultSet continuerà a esistere, ma non si dovrebbe essere in grado di utilizzare il ResultSet come avrebbe dovuto essere chiuso al momento della chiusura della connessione logica. –

+1

E se si tratta di un'implementazione errata di WebSphere: dipende da cosa si utilizza come 'ConnectionPoolDataSource' per' DataSource' di websphere. Il comportamento che ho descritto dovrebbe essere applicato dall'implementazione di 'PooledConnection'. –

3

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

Questo chiuderà la connessione fisica stabilita al database e tutto il viz risorse. Resultset, Statement, Connection sono rilasciati. Pertanto, non è possibile accedervi dopo la chiusura della connessione.

connection2.close() (attraverso DataSource.getConnection())

Questo è DataSource attuazione dipendente e quindi il comportamento non deve essere costante attraverso diverse implementazioni DataSource. Inoltre, all'interno di una determinata implementazione DataSource, il ciclo di vita effettivo della connessione dipende da vari altri parametri che si consiglia vivamente di non differenziare questa connessione da quella ottenuta tramite DriverManager.

Se si vuole veramente i dati contenuti nel ResultSet ad essere disponibile dopo la Statement e Connection sono chiusi, è possibile dare un'occhiata a CachedRowSet se che misura il vostro caso d'uso.

+2

Le connessioni logiche ottenute da un pool di connessioni devono comportarsi (per l'utente) esattamente come le connessioni fisiche ottenute da DriverManager. Quindi per l'utente la connessione e tutti gli oggetti dipendenti dovrebbero apparire chiusi, anche se la connessione fisica rimane aperta. Se un'implementazione dell'origine dati si comporta diversamente, non riesce a soddisfare le specifiche JDBC. –

3

La memorizzazione nella cache sul lato client potrebbe dipendere dal driver utilizzato per la connessione. Ma alcuni driver ti impediscono specificamente di utilizzare un'istruzione o un set di risultati una volta che la connessione è stata chiusa. Altri mantengono il set di risultati sul lato client