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

StackOverflow https://stackoverflow.com/questions/128527

Question

Nous avons nos serveurs JBoss et Oracle sur des serveurs distincts. Les connexions semblent avoir été abandonnées et posent des problèmes avec JBoss. Comment puis-je faire en sorte que JBoss se reconnecte à Oracle si la connexion est mauvaise et que nous comprenons pourquoi les connexions sont abandonnées?

Était-ce utile?

La solution

Il existe généralement une option de configuration sur le pool permettant à une requête de validation d'être exécutée lors d'un emprunt. Si la requête de validation s'exécute correctement, le pool renverra cette connexion. Si la requête ne s'exécute pas correctement, le pool crée une nouvelle connexion.

Le Wiki JBoss documente les divers attributs du pool.

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

On dirait que cela devrait faire l'affaire.

Autres conseils

Bien que vous puissiez utiliser l'ancien & "; sélectionnez 1 parmi deux &"; Le truc, l’inconvénient est qu’il émet une requête supplémentaire chaque fois que vous empruntez une connexion au pool. Pour les gros volumes, cela représente un gaspillage.

JBoss fournit un validateur de connexion spécial à utiliser pour Oracle:

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

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

Cependant, il est toujours inutile d’exécuter cette opération chaque fois qu’une connexion est empruntée. Par conséquent, vous pouvez utiliser l’utilitaire où un thread en arrière-plan vérifie les connexions du pool et élimine les connexions inactives de manière silencieuse. C’est beaucoup plus efficace, mais cela signifie que si les connexions cessent , toute tentative de les utiliser avant que le thread d’arrière-plan ne s'exécute échoue.

Consultez la documentation sur le wiki pour savoir comment configurer la vérification en arrière-plan (recherchez background-validation-millis). .

Pas assez de rep pour un commentaire, donc c'est sous forme de réponse. La méthode 'Select 1 from dual' et la méthode org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker de skaffman sont équivalentes, 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 la mise en œuvre interne du ping par Oracle consiste à effectuer une 'Select 'x' from dual'. Natch.

JBoss propose 2 méthodes pour valider la connexion: - À base de ping ET - Basé sur une requête

Vous pouvez utiliser selon les besoins. 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>

Si vous ne rencontrez pas le bon pilote Oracle chez Jboss, vous risquez de recevoir Classcast ou une erreur liée et, pour cette connexion, de quitter le pool de connexions. Vous pouvez essayer de créer votre propre classe ConnectionValidator en implémentant org.jboss.resource.adapter.jdbc.ValidConnectionChecker l'interface. 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;
   }
}

Nous avons récemment eu des problèmes de gestion des requêtes flottantes causés par des verrous de session oracle oracle DBMS_LOCK conservés indéfiniment dans le pool de connexions côté client.

Voici donc une solution qui force l'expiration de la session en 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 l’obtention des connexions du pool. Assurez-vous de tester ceci sous charge.

Une petite mise à jour de la réponse de @ skaffman. Dans JBoss 7, vous devez utiliser & Quot; nom-classe & Quot; attribut lors de la définition d’un vérificateur de connexion valide et d’un package différent:

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top