Newsgroup: it.comp.java
Titolo: Chiusura coinnection pool.

Ciao a tutti,
sono, ahimé, incastrato in un progetto realizzato nel peggior modo
possibile :-/.
Praticamente la web application sulla quale mi hanno "parcheggiato", è
realizzata completamente con jsp (si, proprio quello che state
pensando, TUTTO IL CODICE JAVA, o quasi, scritto in JSP). Codesto
"ambiente" utilizza una classe unica per connettersi al DB, nella
quale vengono gestiti (oddio, magari getiti :-) ) i cursori, gli
statement e, soprattutto, le aperture di connessione attraverso un
Connection pool di BEA.
Immaginate che esiste un metodo executeQuery(String sql) che riceve la
query, richiede una connessione al data source ed esegue la query
utilizzando, come ResultSet, un'attributo interno.
Esiste, inoltre un boolean next() che incapsula il next sul result set
e tanti metodi get<qualcheccosa> che incapsulano, ad esempio, il
getString, getInt etc. del ResultSet.
Premesso che:
1) ho detto, chiesto e ripetuto di riscrivere daccapo l'applicazione,
ma come immaginate non è possibile;
2) questa classe è richiamata in migliaglia di posti (tutte le jsp,
più volte per pagina);
Mi sorge un problema...
Nei punti in cui viene utilizzata, non viene mai richiamata il metodo
per rilasciare la connessione al DS, avevo cercato di marginare questo
problema facendo eseguire il close degli statement e delle connessioni
appena finiva lo scorrimento del RS, (porcata, ma meglio di niente) ma
purtroppo in molti punti non viene richiamato il next all'interno di
un ciclo, ma solo una volta...
Avete qualche buona idea per far chiudere tutto correttamente
intervenendo se possibili SOLO nella classe in questione?
Una mia idea era, un thread temporizzato che a X secondi dall'ultimo
next effettuava le chiusure, ma sicuramente non è una cosa buona e
giusta...altre idee/suggerimenti a parte il denunciare/uccidere i miei
predecessori?
Grazie mille a tutti.

predecessori?
La soluzione in questi casi e' salvare la connessione in uso dentro il 
thread utilizzando il thread local
(
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ThreadLocal.html
).
Questo lo fai modificando solo la classe di gestione al database.
Poi aggiungi un servlet-filter all'applicazione che alla fine della 
richiesta chiude la connessione (se la fa dare dall'oggetto di gestione del 
database, oppure, meglio, chiede a questo ultimo di chiudere la sua 
connessione).
Quanto detto e' valido se quella classe viene sempre utilizzata come factory 
delle connection.
Per quanto riguarda gli altri oggetti (Statement e ResultSet) stessa cosa. 
Questi pero' molto probabilmente non sono ottenuti dalla classe di gestione 
direttamente, bensi' dalla Connection. In questo caso potresti ritornare un 
wrapper che implementa Connection e gestire la' gli statement e result set 
(il wrapper connection ritorna wrapper di statement).
Ricapitolando, se ti basta la chiusura della connessione che e' sempre 
ottenuta dalla factory ti va abbastanza di lusso (modifichi oggetto database 
e aggiungi filtro).
Altrimenti avrai da smanettare un po' con i wrapper vari. 

un ciclo, ma solo una volta...
Se hai il sorgente - come spero  - di tale classe, IMHO la soluzione più 
"pulita"
è rivedere l'utilizzo della classe e gestire in loco la chiusura delle 
connessioni
ed il rilascio delle connessioni.
Scorpio. 

 
La soluzione piu' pulita e' sicuramente quella di licenziarsi in tronco 
e fuggire da una simile fabbrica di spaghetti code ;) ..ma bisogna anche 
dire che in Italia si rischia di cadere dalla padella alla brace.


Già fatto...sono in preavviso :-)
Cmq, non l'ho fatto per questo (o almeno non solo) problema.
Io, che sono un tipo preciso (anche troppo), anche nel periodo di
preavviso, dò il meglio (o almeno ci provo)! :-P
Cmq, realizzato l'idea (grazie un milione e mezzo) di cicap, sembra
che il suo dovere lo fa...mo lo stresso un pò!

che il suo dovere lo fa...mo lo stresso un pò!
Se sei alle prima armi con i ThreadLocal stai molto attento pero'.
Rilascia sempre il threadlocal prima della fne del thread (alla fine del 
filtro e con un try finally) altrimenti incorri in bug difficili da scovare. 
Dal momento che sicuramente il container fa del thread pooling, se ti scordi 
di pulire l'oggetto con una semplice chiamata
myThreadLocal.set(null);
causerai memory leak o cose ancora peggiori. Mi raccomando!