Une suggestion pratique consiste à ajouter un peu de code de débogage et de création et de fermeture de fichiers de résultats dans un fichier csv. Plus tard, vous pouvez examiner ce fichier et vérifier s'il y a une entrée "close" pour chaque "create".
Donc, en supposant que vous avez une classe utilitaire avec des méthodes statiques qui permet aux cordes d'écriture dans un fichier, vous pouvez le faire comme ceci:
ResultSet rs = stmt.executeQuery(query);
Util.writeln(rs.hashcode() + ";create"); // add this line whenever a
// new ResultSet is created
et
rs.close();
Util.writeln(rs.hashcode() + ";closed"); // add this line whenever a
// ResultSet is closed
Ouvrez le fichier csv avec Excel ou tout autre programme de feuille de calcul, trie la table et regarde si les ensembles de résultats ne sont pas fermés. Si c'est le cas, ajoutez plus d'informations de débogage pour identifier clairement les ensembles ouverts.
BTW - Enveloppement des interfaces (comme JAMon) est assez facile, si vous avez éclipser ou quelque chose d'autre, son code en moins de 15 minutes. Vous auriez besoin d'enrouler Connection, Statement (et PreparedStatement?) Et ResultSet, l'emballage ResultSet pourrait être instrumenté pour suivre et surveiller la création et la fermeture des jeux de résultats:
public MonitoredConnection implements Connection {
Connection wrappedConnection = null;
public MonitoredConnection(Connection wrappedConnection) {
this.wrappedConnection = wrappedConnection;
}
// ... implement interface methods and delegate to the wrappedConnection
@Override
public Statement createStatement() {
// we need MonitoredStatements because later we want MonitoredResultSets
return new MonitoredStatement(wrappedConnection.createStatemet());
}
// ...
}
Même chose pour MonitoredStatement et MonitoredResultSet (MonitoredStatement retournera enveloppées ResultSets):
public MonitoredStatement implements Statement {
private Statement wrappedStatement = null;
@Override
public ResultSet executeQuery(String sql) throws SQLException
MonitoredResultSet rs = wrappedStatement.executeQuery(sql);
ResultSetMonitor.create(rs.getWrappedResultSet()); // some static utility class/method
return rs;
}
// ...
}
et
public MonitoredResultSet implements ResultSet {
private ResultSet wrappedResultSet;
@Override
public void close() {
wrappedResultSet.close();
ResultSetMonitor.close(wrappedResultSet); // some static utility class/method
}
// ...
}
a la fin, vous ne devriez avoir besoin de modifier une seule ligne dans votre code:
Connection con = DriverManager.getConnection(ur);
à
Connection con = new MonitoredConnection(DriverManager.getConnection(ur));
Merci pour le look JAMon. La solution manuelle pour "vérifier le code et s'assurer que tout Statement, PreparedStatement et ResultSet sont fermés" est ennuyeux ;-) et je veux l'éviter. –
La gestion des curseurs ouverts à l'aide d'un outil n'est pas aussi simple. Une chose que vous devrez faire est de voir si ces curseurs sont utilisés ou stagnants et ce n'est pas facile à dire. –