web-dev-qa-db-fra.com

Existe-t-il un moyen pour que le pool de connexions JBoss se reconnecte à Oracle lorsque les connexions se détériorent?

Nous avons notre JBoss et Oracle sur des serveurs séparés. Les connexions semblent être interrompues et posent des problèmes avec JBoss. Comment puis-je faire reconnecter le JBoss à Oracle si la connexion est mauvaise pendant que nous découvrons pourquoi les connexions sont interrompues en premier lieu?

31
Joshua

Il existe généralement une option de configuration sur le pool pour permettre l'exécution d'une requête de validation lors de l'emprunt. Si la requête de validation s'exécute correctement, le pool renvoie cette connexion. Si la requête ne s'exécute pas correctement, le pool créera une nouvelle connexion.

Le JBoss Wiki documente les différents attributs du pool.

<check-valid-connection-sql>select 1 from dual</check-valid-connection-sql>

On dirait que ça devrait faire l'affaire.

27
Steve K

Bien que vous puissiez utiliser l'ancienne astuce "sélectionner 1 parmi les deux", l'inconvénient est qu'il émet une requête supplémentaire à chaque fois que vous empruntez une connexion à la piscine. Pour des volumes élevés, c'est du gaspillage.

JBoss fournit un validateur de connexion spécial qui devrait être utilisé pour Oracle:

<valid-connection-checker-class-name>
    org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker
</valid-connection-checker-class-name>

Cela utilise la méthode propriétaire ping () sur la classe de connexion Oracle JDBC et utilise le code réseau sous-jacent du pilote pour déterminer si la connexion est toujours active.

Cependant, il est toujours inutile de l'exécuter à chaque fois qu'une connexion est empruntée, vous pouvez donc utiliser la fonction où un thread d'arrière-plan vérifie les connexions dans le pool et élimine silencieusement les connexions mortes. Ceci est beaucoup plus efficace, mais signifie que si les connexions tombent en panne, toute tentative de les utiliser avant l'exécution du thread d'arrière-plan échouera.

Voir wiki docs pour savoir comment configurer la vérification en arrière-plan (recherchez background-validation-millis).

33
skaffman

Pas assez de représentant pour un commentaire, donc c'est sous la forme d'une réponse. Le 'Select 1 from dual' et skaffman org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker la méthode est équivalente, bien que la vérification de la connexion fournisse un niveau d'abstraction. Nous avons dû décompiler les pilotes Oracle jdbc pour un exercice de dépannage et l'implémentation interne d'Oracle du ping consiste à effectuer un 'Select 'x' from dual'. Natch.

9
abh

JBoss propose 2 façons de valider la connexion: - basée sur Ping ET - basée sur requête

Vous pouvez utiliser selon l'exigence. Ceci est planifié par un thread séparé selon la durée définie dans le fichier de configuration de la source de données.

<background-validation>true</background-validation> <background-validation-minutes>1</background-validation-minutes>

Parfois, si vous n'avez pas le bon pilote Oracle chez Jboss, vous pouvez obtenir une diffusion de classe ou une erreur connexe et pour cette connexion, le décrochement du pool de connexions peut commencer. Vous pouvez essayer de créer votre propre classe ConnectionValidator en implémentant l'interface org.jboss.resource.adapter.jdbc.ValidConnectionChecker. Cette interface ne fournit qu'une seule méthode 'isValidConnection()' et attend 'NULL' en retour d'une connexion valide.

Ex:

public class OracleValidConnectionChecker implements ValidConnectionChecker, Serializable {

   private Method ping;

   // The timeout (apparently the timeout is ignored?)
   private static Object[] params = new Object[] { new Integer(5000) };

   public SQLException isValidConnection(Connection c) {

       try {
           Integer status = (Integer) ping.invoke(c, params);

           if (status.intValue() < 0) {
               return new SQLException("pingDatabase failed status=" + status);
           }

       }
       catch (Exception e) {
           log.warn("Unexpected error in pingDatabase", e);
       }

       // OK
       return null;
   }
}
6
arviarya

Nous avons récemment rencontré des échecs de gestion des demandes flottantes causés par des orphelins Oracle DBMS_LOCK verrous de session conservés indéfiniment dans le pool de connexions côté client.

Voici donc une solution qui force l'expiration de la session dans 30 minutes mais n'affecte pas le fonctionnement de l'application:

<check-valid-connection-sql>select case when 30/60/24 > sysdate-LOGON_TIME then 1 else 1/0 end 
from V$SESSION where AUDSID = userenv('SESSIONID')</check-valid-connection-sql>

Cela peut impliquer un certain ralentissement dans le processus d'obtention de connexions à partir du pool. Assurez-vous de tester cela sous charge.

3
Vadzim

Une petite mise à jour de la réponse de @ skaffman. Dans JBoss 7, vous devez utiliser l'attribut "class-name" lorsque vous définissez un vérificateur de connexion valide et le package est différent:

<valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.Oracle.OracleValidConnectionChecker" />

2
Jakub Godoniuk