2010-01-23 4 views
6

J'ai une application Java qui ouvre une connexion à une base de données au début, et la ferme à la fin. Toutefois, le programme ne se termine pas toujours, car une exception est levée ou je le débogue et l'arrête à mi-parcours.Problème avec la fermeture de la connexion db lors du débogage?

Est-ce que cela va provoquer des connexions ouvertes pour empiler et ralentir la base de données, ou sera-t-elle nettoyée automatiquement?

Répondre

8

Une base de données de connexion est détenue et gérée par la base de données, la classe donne juste vous accédez à cette ressource de base de données. Si vous ne fermez pas la connexion, la classe Java peut être récupérée, mais la base de données ne peut pas indiquer que la connexion n'est plus utilisée, ce qui peut entraîner le gaspillage des ressources de la base de données) ou même fuite.

Donc, quand vous avez terminé avec l'aide de votre Connection, vous devriez être sûr de fermer explicitement en appelant sa méthode close(). Cela permettra au garbage collector de se rappeler la mémoire le plus tôt possible et, plus important, il libère toutes les autres ressources de base de données (curseurs, poignées, etc) la connexion peut être maintenue.

La manière traditionnelle de faire en Java est de fermer votre ResultSet, Statement et Connection (dans cet ordre) dans un bloc finally lorsque vous avez terminé avec eux et le modèle sécuritaire ressemble que:

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 */} 
    } 
} 

le bloc finally peut être légèrement améliorée en (pour éviter le contrôle null):

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

Mais, encore, ce qui est extrêmement bavard si vous vous généralement à l'aide une classe d'aide pour fermer les objets dans les méthodes d'assistance null-sécurité et le bloc finally devient quelque chose comme ça:

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

Et, en fait, la Apache Commons DbUtils a une classe DbUtils qui fait précisément il n'y a donc pas besoin de écrivez votre propre. Dans votre cas, cela résoudra le problème de l'exception, mais pas celui du débogage (et vous gaspillerez des ressources de base de données jusqu'à ce que le délai d'expiration se produise du côté de la base de données). Donc, 1. ne déboguez pas votre code en utilisant une base de données de production. 2. essayez d'exécuter votre session de débogage jusqu'à la fin.

+1

Les gars de Sun étaient INSANE quand ils ont décidé de ne pas avoir de destructeurs. Il était beaucoup plus facile de fermer toutes les ressources ouvertes dans les destructeurs comme en C++. Maintenant, regardez tout ce que nous avons besoin d'écrire pour une petite requête de base de données ... Cela aurait dû être fait en 3 lignes de code: se connecter à db, exécuter une requête, obtenir un résultat. –

0

Non. Si votre programme se poursuit et que vos connexions sont actives, le BD a simplement rejeté votre phrase.

Si quelque chose se produisait avec votre connexion (par exemple, un délai d'attente), le BD était celui qui fermait cette connexion et ne consommait pas de ressources.

Si vous avez libéré votre connexion et que le garbage collector a été appelé (cela peut prendre un certain temps), la connexion se fermera avant d'être libérée.

Si votre programme s'est terminé sans fermer votre connexion, alors tout le processus (système d'exploitation) va libérer ses ressources natives, et entre elles, la ressource native qui s'est connectée au BD (probable une prise réseau). Le BD recevra alors la connexion interrompue/fermée et relâchera votre connexion. La seule chose qui pourrait arriver est qu'une seule exécution se connecterait plusieurs fois au BD et ferait des choses très mauvaises pour les garder ouvertes, occupant toutes les connexions disponibles. Mais ce n'est pas ton cas je pense.

Modifier: BD générales sont faites de mauvais client comportement -Preuve

2

Voici ce que Sun (err ... Oracle?) says:

Il est recommandé que les programmeurs fermer explicitement les connexions et les déclarations qu'ils ont créées lorsqu'ils ne sont plus nécessaires. Un programmeur écrivant du code dans le langage de programmation Java et n'utilisant aucune ressource extérieure n'a pas besoin de s'inquiéter de la gestion de la mémoire. Le garbage collector supprime automatiquement les objets lorsqu'ils ne sont plus utilisés et libère la mémoire qu'ils utilisaient. Lorsque la mémoire est faible, il va recycler les objets mis au rebut, rendant la mémoire qu'ils occupent actuellement disponible pour une réutilisation rapide. Toutefois, si une application utilise des ressources externes, comme elle le fait lorsqu'elle accède à un SGBD avec l'API JDBC, le garbage collector n'a aucun moyen de connaître l'état de ces ressources. Il recyclera toujours les objets mis au rebut, mais s'il y a beaucoup de mémoire libre dans le tas Java, il se peut que le garbage collecter rarement, même si la (petite) quantité de Java retient de grandes quantités de ressources coûteuses. Par conséquent, il est recommandé que les programmeurs ferment explicitement toutes les connexions (avec la méthode Connection.close) et les instructions (avec la méthode Statement.close) dès qu'elles ne sont plus nécessaires, libérant ainsi les ressources SGBD le plus tôt possible. Cela s'applique en particulier aux applications qui sont destinées à fonctionner avec différents SGBD en raison des variations d'un SGBD à un autre.

Je voudrais mettre l'accès à la base de données dans un bloc try et assurez-vous de fermer toutes les instructions et les connexions dans un bloc finally.

2

Votre serveur db aura un paramètre de délai d'expiration. Il fermera la connexion et annulera toutes les transactions non validées. Cela se produit depuis des décennies sur tout produit db capable de produire.

Si vous voulez le faire correctement utiliser un try {} ..votre code .. finally {..} connexions ..close

+0

De plus, la plupart des protocoles de base de données ping sur l'autre côté pour voir s'il est actif. –

Questions connexes