Discussione:
Statement e Resultset
(troppo vecchio per rispondere)
Andrea
2007-02-21 19:58:21 UTC
Permalink
Ciao a tutti,
Io ho un metodo java (incluso in una classe java) come questo qui sotto:

public static ResultSet eseguiSelect(Connection conn,String query) throws
SQLException
{
LogTrace log = new LogTrace();
log.trace("query : "+query);
Statement stmt = null;
ResultSet rs=null;
try
{
stmt=conn.createStatement();
rs=stmt.executeQuery(query);
}
catch(SQLException sqle)
{
log.trace("SQLException : "+sqle.getMessage());
log.trace("SQLState : "+sqle.getSQLState());
log.trace("VendorError : "+sqle.getErrorCode());
try
{
rs.close();
stmt.close();
}
catch(Exception exception)
{ }
throw sqle;
}
return rs;
}


In questa elaborazione non chiudo "stmt" e "rs" perchè "rs" deve essere
ritornato al chiamante del metodo; ma ciò può portare a problemi? Ossia,
questi statement e resultset non chiusi restano "attivi" con conseguente
progressiva occupazione di memoria ad ogni chiamata?
Grazie sin d'ora per l'aiuto che potrete darmi.
JFM
SoulSpirit
2007-02-21 21:55:50 UTC
Permalink
Post by Andrea
In questa elaborazione non chiudo "stmt" e "rs" perchè "rs" deve essere
ritornato al chiamante del metodo; ma ciò può portare a problemi?
Quando chiudi la Connection, di norma vengono chiusi anche tutti e
ResultSet da essa dipendenti. Se pero' non chiudi la Connection allora
son c***i.
Comunque e' buona norma creare (o meglio, richiedere) la Connection ogni
qualvolta si ha bisogno di eseguire una query, e chiuderla subito dopo.
In situazioni normali un metodo public non dovrebbe mai ritornare un
ResultSet, ma semmai una tua struttura dati contenente le informazioni
estrapolate dal ResultSet.
--
SoulSpirit
gnurant
2007-02-21 23:11:10 UTC
Permalink
Post by SoulSpirit
Post by Andrea
In questa elaborazione non chiudo "stmt" e "rs" perchè "rs" deve essere
ritornato al chiamante del metodo; ma ciò può portare a problemi?
Quando chiudi la Connection, di norma vengono chiusi anche tutti e
ResultSet da essa dipendenti. Se pero' non chiudi la Connection allora
son c***i.
Comunque e' buona norma creare (o meglio, richiedere) la Connection ogni
qualvolta si ha bisogno di eseguire una query, e chiuderla subito dopo.
In situazioni normali un metodo public non dovrebbe mai ritornare un
ResultSet, ma semmai una tua struttura dati contenente le informazioni
estrapolate dal ResultSet.
La risposta di SoulSpirit mi sembra un po' imprecisa.
In effetti una medesima Connection può essere utilizzata per più query,
mentre lo Statement deve venir utilizzato per una sola query: tipicamente
istanzi lo Statement, esegui la query, utilizzi il ResultSet (per es., come
dice SoulSpirit, riversandolo in una tua struttura idonea), poi chiudi il
ResultSet (facoltativo) e quindi anche lo Statement (che chiude anche il
ResultSet). Se chiudi lo Statement prima di aver utilizzato il ResultSet
incorri in una eccezione, se lo lasci aperto potresti avere comportamenti
imprevedibili (vedi varia documentazione Sun per dettagli più edificanti).
La Connection invece dovrebbe venir gestita tramite un apposito Pool, per
cui al posto del metodo close() che chiude effettivamente anche la
connessione alla sorgente JDBC si userà un metodo (anche close() overridato)
che rilascia la connessione rendendola disponibile per un ulteriore
utilizzo. Trovi cmq molta documentazione in giro..
r***@email.it
2007-02-21 23:46:46 UTC
Permalink
Post by Andrea
Ciao a tutti,
public static ResultSet eseguiSelect(Connection conn,String query) throws
SQLException
{
LogTrace log = new LogTrace();
log.trace("query : "+query);
Statement stmt = null;
ResultSet rs=null;
try
{
stmt=conn.createStatement();
rs=stmt.executeQuery(query);
}
catch(SQLException sqle)
{
log.trace("SQLException : "+sqle.getMessage());
log.trace("SQLState : "+sqle.getSQLState());
log.trace("VendorError : "+sqle.getErrorCode());
try
{
rs.close();
stmt.close();
}
catch(Exception exception)
{ }
throw sqle;
}
return rs;
}
In questa elaborazione non chiudo "stmt" e "rs" perchè "rs" deve essere
ritornato al chiamante del metodo; ma ciò può portare a problemi? Ossia,
questi statement e resultset non chiusi restano "attivi" con conseguente
progressiva occupazione di memoria ad ogni chiamata?
Grazie sin d'ora per l'aiuto che potrete darmi.
JFM
E' un pessima idea tenere aperto un resultset. Non per la memoria
consumata,
ma perche' il resultset e' solo un puntatore ai dati , che sono ancora
sul db.
Leggi i dati dal resultset e trasferiscili su un' altra struttura
dati, tipo un 'arraylist.
O sei vuoi una specie di resultset disconnesso puoi usare la classe
Result
che fa parte dell'implementazione di JSTL.
http://www.jajakarta.org/taglibs/standard-1.0/doc/javadoc/javax/servlet/jsp/jstl/sql/ResultSupport.html
Con la classe ResultSupport hia pure un bel metodo preconfezionato che
ti inscatola
i dati del ResultSet in un Result, cosi puoi chiudere connection,
resultset e statement.

Continua a leggere su narkive:
Loading...