Pour diverses raisons, les connexions dans un pool peuvent devenir invalides: délai de connexion du serveur, problèmes de réseau ...
D'après ce que je comprends, un pool de connexions Tomcat JDBC ne fournit aucune garantie quant à la validité des connexions qu'il fournit à l'application.
Pour éviter (en fait seulement de réduire le risque) d'obtenir une connexion non valide à partir du pool, une solution semble être la configuration de la validation des connexions. Valider une connexion signifie exécuter une requête très basique sur la base de données (par exemple SELECT 1;
sur MySQL).
Tomcat JDBC Connection Pool propose plusieurs options pour tester la connexion. Les deux que je trouve les plus intéressantes sont testOnBorrow
et testWhileIdle
.
Au début, je pensais que testOnBorrow
est la meilleure option car elle valide essentiellement la connexion avant de la fournir à l'application (avec une fréquence maximale définie par validationInterval
).
Mais au bout d'une seconde, j'ai réalisé que tester la connexion juste avant de l'utiliser pouvait avoir un impact sur la réactivité de l'application. Je pense donc que l'utilisation de testWhileIdle
peut être plus efficace car elle teste les connexions alors qu'elles ne sont pas utilisées.
Peu importe l'option que je choisis, il semble qu'ils ne font que réduire le risque d'obtenir une connexion non valide, mais ce risque existe toujours.
Je finis donc par demander: dois-je utiliser testOnBorrow
ou testWhileIdle
ou un mélange des deux?
En passant, je suis surpris que validationInterval
ne s'applique pas à testOnReturn
et je ne comprends pas vraiment le but de testOnConnect
.
Il n'y a pas de bonne réponse à 100% à cela. C'est une question de compromis et de contexte.
Mais en considérant cela comme un cas d'angle, le testOnBorrow donne une assez bonne assurance.
Maintenant, le compromis avec cela est que, chaque fois que vous demandez une connexion, une requête (quelle que soit sa légèreté) est effectuée sur le serveur de base de données. Cela peut être très rapide, mais le coût n'est toujours pas nul.
Et si vous avez une application occupée, avec une très bonne fiabilité de connexion à la base de données, alors vous commencerez à voir à partir des données, que le COÛT de "vérification de validité sur chaque demande de connexion du pool" l'emporte sur les avantages de détecter les problèmes de connexion .
Il garantit au maximum que vous avez une bonne connexion avant de l'utiliser. Surtout si l'on considère le coût (nouvelle tentative + intervention manuelle + perte de flux de travail, etc.) de "ne pas pouvoir récupérer facilement" d'une opération de base de données ayant échoué.
Imaginez maintenant si vous avez l'option testOnIdle. Cela nécessite que vos connexions deviennent inactives (en fonction du délai d'inactivité de la connexion) avant qu'un contrôle d'intégrité puisse être effectué.
Et un dernier point de données est que pour certaines applications, le chemin critique n'est pas le temps de la "requête de validation" (en millisecondes, je l'espère). Les applications ont de plus gros problèmes à traiter. Et bien sûr, pour certaines applications, ce temps est très important.
Juste pour vous faire savoir, je viens de le tester et il est possible d'utiliser à la fois les propriétés testOnBorrow
et testOnIdle
.
Comme mentionné ci-dessus, cependant, j'opterai pour testOnBorrow
uniquement en raison du fait que mon application n'est pas soumise à un trafic important et peut se permettre de valider une connexion avant de la saisir.
Comme indiqué dans les commentaires, testOnBorrow
ne nécessite pas de requête de validation. Si vous choisissez d'en garder un, il peut s'agir d'une simple sélection:
jdbc.Hive.testOnBorrow=true
jdbc.Hive.validationQuery=SELECT 1
Si vous souhaitez utiliser testWhileIdle
, vous pouvez utiliser ce qui suit:
jdbc.testWhileIdle=true
jdbc.minEvictableIdleTimeMillis=1800000
jdbc.timeBetweenEvictionRunsMillis=1800000`
Plus d'informations sur DBCP: https://commons.Apache.org/proper/commons-dbcp/configuration.html