132 votes

Fermeture des connexions à la base de données en Java

Je suis un peu confus, je lisais le ci-dessous de http://en.wikipedia.org/wiki/Java_Database_Connectivity

Connection conn = DriverManager.getConnection(
     "jdbc:somejdbcvendor:other data needed by some jdbc vendor",
     "myLogin",
     "myPassword" );

Statement stmt = conn.createStatement();
try {
    stmt.executeUpdate( "INSERT INTO MyTable( name ) VALUES ( 'my name' ) " );
} finally {
    //It's important to close the statement when you are done with it
    stmt.close();
}

N'avez-vous pas besoin de fermer la Connexion conn? Ce qui se passe si les conn.close() ne se produit pas?

J'ai une web app, je suis le maintien qui n'est pas actuellement à proximité une ou l'autre forme, mais est le plus important vraiment la stmt, conn, ou les deux?

Le site continue à aller vers le bas de façon intermittente, mais le serveur continue à dire que c'est une base de données de problème de connexion, je soupçonne que ce n'est pas fermée, mais je ne sais pas qui, si tout fermer.

216voto

Pascal Thivent Points 295221

Lorsque vous avez terminé avec l'aide de votre Connection, vous devez fermer explicitement en appelant son close() méthode afin de libérer tous les autres ressources de base de données (curseurs, poignées, etc.), la connexion peut être tenue sur.

En fait, le coffre-fort de modèle en Java est de fermer votre ResultSet, Statement, et Connection (dans cet ordre) en finally bloc lorsque vous avez terminé avec eux, quelque chose comme ça:

Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;

try {
    // Do stuff
    ...

} catch (SQLException ex) {
    // Exception handling stuff
    ...
} finally {
    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException e) { /* ignored */}
    }
    if (ps != null) {
        try {
            ps.close();
        } catch (SQLException e) { /* ignored */}
    }
    if (conn != null) {
        try {
            conn.close();
        } catch (SQLException e) { /* ignored */}
    }
}

L' finally bloc peut être légèrement améliorée (pour éviter le nul à vérifier):

} finally {
    try { rs.close(); } catch (Exception e) { /* ignored */ }
    try { ps.close(); } catch (Exception e) { /* ignored */ }
    try { conn.close(); } catch (Exception e) { /* ignored */ }
}

Mais, la encore, ce qui est extrêmement détaillé de sorte que vous finissent généralement à l'aide d'une classe d'aide à fermer les objets en null-safe méthodes d'assistance et l' finally bloc devient quelque chose comme ça:

} finally {
    DbUtils.closeQuietly(rs);
    DbUtils.closeQuietly(ps);
    DbUtils.closeQuietly(conn);
}

Et, effectivement, l' Apache Commons DbUtils a un DbUtils de la classe qui est justement donc il n'est pas nécessaire d'écrire votre propre.

68voto

Yadu Krishnan Points 204

Il est toujours préférable de fermer la base de données/objets de ressource après utilisation. Mieux pour fermer la connexion, le jeu de résultats et de déclaration des objets dans l' finally bloc.

Jusqu'à ce que Java7, toutes ces ressources doit être fermé à l'aide d'un finally bloc. Si vous êtes à l'aide de Java 7, puis de la fermeture de la ressources que vous pouvez faire comme suit.

try(Connection con = getConnection(url, username, password, "org.postgresql.Driver");
    Statement stmt = con.createStatement();
    ResultSet rs = stmt.executeQuery(sql);
) {

//statements
}catch(....){}

Maintenant, con, stmt et rs objets deviennent une partie de bloc try et java se ferme automatiquement ces ressources après utilisation.

Espère que j'ai été utile.

14voto

Grigori A. Points 705

Il suffit de fermer juste Statement et Connection. Il n'est pas nécessaire de fermer explicitement l' ResultSet objet.

La documentation Java dit à propos de l' java.sql.ResultSet:

Un objet ResultSet est automatiquement fermé par la Déclaration de l'objet qui les a générés lors de la Déclaration de l'objet est fermé, ré-exécuté, ou est utilisé pour récupérer le résultat suivant à partir d'une séquence de plusieurs résultats.


Grâce BalusC pour les commentaires: "je ne voudrais pas compter sur cela. Certains pilotes JDBC échouer."

11voto

Brian Agnew Points 143181

Oui. Vous devez fermer le jeu de résultats, l'état et la connexion. Si la connexion est venu d'une piscine, clôture, il envoie de nouveau à la piscine pour une réutilisation.

Vous avez l'habitude de le faire dans un finally{} bloc, de telle sorte que si une exception est levée, vous avez toujours la possibilité de fermer cette.

De nombreux cadres de s'occuper de cette ressource d'allocation/désallocation de problème pour vous. par exemple, au Printemps JdbcTemplate. Apache DbUtils a des méthodes pour s'occuper de la fermeture de la resultset/déclaration/connexion si la valeur null ou pas (et attraper les exceptions à la clôture), ce qui peut aussi aider.

7voto

Alex Miller Points 28225

Oui, vous devez fermer la connexion. Sinon, le client de base de données laissera généralement ouverte la connexion de socket et les autres ressources.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X