web-dev-qa-db-fra.com

Fermeture des connexions JDBC dans le pool

Notre section de code standard d'utilisation de JDBC est ...

Connection conn = getConnection(...);
Statement  stmt = conn.conn.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE,
                                                ResultSet.CONCUR_READ_ONLY);
ResultSet  rset = stmt.executeQuery (sqlQuery);

// do stuff with rset

rset.close(); stmt.close(); conn.close();

Question 1: Lorsque vous utilisez Connection Pool, faut-il fermer la connexion à la fin? Si oui, le but de la mise en commun n'est-il pas perdu? Et si non, comment la source de données sait-elle quand une instance particulière de Connection est libérée et peut être réutilisée? Je suis un peu confus sur celui-ci, tous les indicateurs sont appréciés.

Question 2: La méthode suivante est-elle proche de la norme? Cela ressemble à une tentative de connexion à partir du pool. Si DataSource ne peut pas être établi, utilisez l'ancien DriverManager. Nous ne savons même pas quelle partie sera exécutée au moment de l'exécution . Répétant la question ci-dessus, faut-il fermer la connexion issue d'une telle méthode?

Merci, MS.

synchronized public Connection getConnection (boolean pooledConnection)
                                                        throws SQLException {
        if (pooledConnection) {
                if (ds == null) {
                        try {
                                Context envCtx = (Context)
                                        new InitialContext().lookup("Java:comp/env");
                                ds = (DataSource) envCtx.lookup("jdbc/NamedInTomcat");
                                return ds.getConnection();
                        } catch (NamingException e) {
                                e.printStackTrace();
                }}
                return (ds == null) ? getConnection (false) : ds.getConnection();
        }
        return DriverManager.getConnection(
                "jdbc:mysql://"+ipaddy+":"+dbPort +"/" + dbName, uName, pWord);
}

Edit: Je pense que nous obtenons la connexion en pool car nous ne voyons pas de trace de pile.

97
Manidip Sengupta

Lors de l'utilisation du pool de connexions, faut-il fermer la connexion à la fin? Si tel est le cas, l'objectif du pooling n'est-il pas perdu? Sinon, comment le DataSource sait-il qu'une instance particulière de Connection est libérée et Je suis un peu confus sur celui-ci, aucun indicateur apprécié.

Oui, vous devez également fermer la connexion en pool. C'est en fait un wrapper autour de la connexion réelle. Sous les capots, libérez la connexion réelle vers la piscine. Il incombe ensuite au pool de décider si la connexion réelle sera en fait fermée ou réutilisée pour un nouvel appel getConnection(). Ainsi, que vous utilisiez ou non un pool de connexions, vous devriez toujours fermer toutes les ressources JDBC en ordre inverse dans le bloc finally du bloc try où vous les avez acquises. En Java 7, ceci peut être encore simplifié en utilisant try-with-resources statement.


La méthode suivante ressemble-t-elle à la méthode standard? Ressemble à une tentative de connexion au pool. Si DataSource ne peut pas être établie, utilisez l'ancien DriverManager. Nous ne savons même pas quelle partie sera exécutée à l'exécution. En répétant la question ci-dessus, faut-il fermer la connexion issue d'une telle méthode?

L'exemple est assez effrayant. Il vous suffit de rechercher/initialiser la DataSource une seule fois au démarrage de l'application dans un constructeur/initialisation d'une classe de configuration DB d'application globale. Ensuite, appelez simplement getConnection() sur la même source de données pendant le reste de la durée de vie de l’application. Pas besoin de synchronisation ni de nullchecks.

Voir également:

108
BalusC

Les pools vous renvoient généralement un objet Connection encapsulé, où la méthode close () est remplacée, renvoyant généralement la connexion au pool. Appeler close () est correct et probablement toujours nécessaire.

Une méthode close () ressemblerait probablement à ceci:

public void close() throws SQLException {
  pool.returnConnection(this);
}

Pour votre deuxième question, vous pouvez ajouter un enregistreur pour indiquer si le bloc inférieur est exécuté. J'imagine que vous ne voudriez que d'une manière ou d'une autre pour la configuration de vos connexions à la base de données. Nous utilisons uniquement un pool pour nos accès à la base de données. Quoi qu'il en soit, il serait très important de fermer la connexion pour éviter les fuites.

21
taer

En fait, la meilleure approche de la gestion des connexions consiste à ne pas les appliquer à un code, où que ce soit. 

Créez une classe SQLExecutor constituant le seul et unique emplacement permettant d'ouvrir et de fermer les connexions. 

Le reste de l'application envoie ensuite des instructions à l'exécuteur plutôt que de créer des connexions à partir du pool et de les gérer (ou de les gérer mal) un peu partout.

Vous pouvez avoir autant d'instances de l'exécuteur que vous le souhaitez, mais personne ne devrait écrire de code ouvrant et fermant des connexions pour son propre compte.

Cela vous permet également de consigner tout votre code SQL à partir d’un seul ensemble de code.

0
Rodney P. Barbati