Pages

dimanche 10 mars 2013

Pool tomcat-jdbc : gérer les problèmes d'accès à la datasource


Tomcat-jdbc-pool est un nouveau pool de connexion introduit à partir de Tomcat 7 en remplacement du pool de connexion commons-pool généralement utilisé sous les versions antérieures de Tomcat. Toutes les options de configuration ont été reprises et d'autres ont été rajoutées ce qui vous permettra facilement de migrer de commons-pool à tomcat-jdbc-pool.

Je vous propose une série d'articles sur le sujet 


Gérer les problèmes d'accès à la datasource 

Les pools de connexion doivent fournir un mécanisme permettant de valider si une connexion est toujours opérationnelle. En effet en cas de problème d'accès à la base de données (coupure de la base, problème réseau) , le pool ne sait pas que la connexion a été perdue et il continue de la délibérer à l'application qui en demande une. La seule façon de vraiment valider une connexion est de faire un aller-retour vers la base de données, afin de garantir que la session est toujours active.

Cette étape supplémentaire peut amener des dégradations de performances si la requête de validation est exécutée trop souvent. A contrario si les vérifications sont trop éloignées on risque d'avoir un grand nombre de connexions périmées inutilisables et non fermées.

On utilise souvent les paramètres
  • testOnBorrow :indique si les objets doivent être validés avant de récupérer une connexion dans le pool. Actif que si la valeur est à true et validationQuery renseignée (vous pouvez aussi utiliser testWhileIdle ou testOnReturn mais ces tests de connexion ne se font pas au moment opportun) 
  • validationQuery qui est la requête qui sera executée (select 1 from dual sous Oracle) 

Pour les applications qui ouvrent de nombreuses connexions nous pouvons avoir des problèmes de performance avec une telle configuration. Tomcat-jdbc-pool offre une nouvelle alternative avec le paramètre validationInterval qui évite de faire des requêtes de validation trop souvent. Au lieu de le faire à chaque connexion on attendra au moins le délai indiqué (en secondes)

Depuis Java 6, l'API JDBC gère directement ce problème de validation en fournissant un appel isValid dans l'interface java.sql.Connection. Tomcat-jdbc-pool offre une alternative pour utiliser ce mécanisme.

Vous pouvez déclarer une classe implémentant l'interface org.apache.tomcat.jdbc.pool.Validator (cette classe doit disposer d'un constructeur vide) et la déclarer dans la propriété validatorClassName de votre datasource. Si cette propriété est spécifiée cette classe sera utilisée à la place de la requête de validation exposée précédemment.

Prenons un exemple de validator. Créez un projet web utilisant comme dépendance la librairie tomcat-jdbc.jar. Nous allons déclarer la classe ConnectionValidator


public class ConnectionValidator implements Validator {

 public ConnectionValidator() { 

 } 

 @Override 
 public boolean validate(Connection connection, int i) { 
    try{ 
        System.out.println("Validation JDBC de la connexion : timeout "); 
        //le timeout permet de fixer une période à partir de laquelle un
        //absence de réponse sera considéré comme une réponse négative 
        return connection.isValid(60); 
    } 
    catch (SQLException e){ 
        e.printStackTrace(); 
        throw new RuntimeException(e); 
    }
 } 
} 

Pour information l'integer passé en paramètre à la fonction validate identifie à quel moment le test est fait. Plusieurs constantes sont mises à disposition


Cette classe peut ensuite être packagée dans un jar que vous devrez ajouter dans les dépendances Tomcat (copie du jar dans le répertoire lib)

Au niveau de la déclaration de la datasource dans le fichier server.xml vous devrez rajouter (en plus des paramètres testOnBorrow et validationQuery)

validatorClassName="com.ehret.tomcat.ConnectionValidator".

2 commentaires:

  1. Bonjour,
    le chemin déclaré validator ClassName ="projet.com.ConnectionValidator".

    ="projet.com celà correspond au context ( package ), c'est bien çà ???

    J'ai un soucis au démarrage du tomcat il affiche :
    févr. 27, 2014 5:04:54 PM org.apache.tomcat.jdbc.pool.PoolProperties setValidatorClassName
    WARNING: The class projet.com.ConnectionValidator cannot be found.
    merci.

    RépondreSupprimer
  2. La datasource définie dans le serveur d'application est initiée au démarrage de Tomcat avant le chargement des webapps. Il faut donc que le Validator custom soit présent dans le contexte Tomcat. Pour celà le mieux est de placer le validator dans un jar indépendant et d'ajouter ce jar dans le répertoire lib de Tomcat

    RépondreSupprimer

Remarque : Seul un membre de ce blog est autorisé à enregistrer un commentaire.