2014-06-24 7 views
0

Je rencontre un problème avec le pool de connexions sur qui distribue des connexions de base de données mortes. J'utilise Glassfish 3.1.2.2 en utilisant jconn3 (com.sybase.jdbc3) pour me connecter à Sybase 12.5. Notre organisation a un processus de redémarrage nocturne pendant lequel nous redémarrons le serveur Sybase. Mon problème se manifeste lors d'une tentative d'utilisation d'une connexion à une base de données au cours du redémarrage. Voici l'ordre des opérations pour générer mon problème:Les connexions mortes sont renvoyées au pool de connexions JDBC - Glassfish 3.1.2.2

  • Sybase est en attente de redémarrage.
  • La connexion est demandée depuis le pool.
  • L'opération de base de données échoue comme prévu.
  • La connexion est renvoyée dans le pool à l'état fermé.
  • Sybase est de retour.
  • La connexion est demandée depuis le pool.
  • L'opération de base de données échoue en raison de l'exception "La connexion est déjà fermée".
  • Connection est retourné à la piscine
  • J'ai mis en place un singleton de récupération de base de données qui tente de se remettre de ce scénario. Chaque fois qu'une exception de base de données se produit, j'effectue un appel jmx pour suspendre toutes les files d'attente et exécuter une opération flushConnectionPool sur le pool de connexions JDBC. Si la connexion à la base de données n'est toujours pas établie, le processus configure une minuterie pour réessayer dans 10 minutes. Bien que ce processus fonctionne, il n'est pas sans défauts.

    Je me rends compte qu'il existe un paramètre sur le pool de sorte que vous pouvez avoir besoin de validation sur la connexion à la base de données avant de le distribuer, mais j'ai évité cela pour des raisons de performances. Mon processus effectue environ 5 millions de transactions de base de données par jour.

    Ma question est, est-ce que quelqu'un connaît un moyen d'éviter de retourner une connexion morte à la piscine en premier lieu?

    Répondre

    1

    Vous avez assez bien résumé vos options. Nous avons eu ce problème, la DB de minuit est tombée. Pour nous, nous avons activé la validation de connexion, mais nous n'avons pas votre volume de transactions. Glassfish offre une option de validation personnalisée, avec laquelle une classe peut être spécifiée pour effectuer la validation.

    Par défaut, toutes les classes fournies par Glassfish ne (vous les verrez proposées en option dans la console) est une instruction SQL comme ceci:

    SELECT 1; 
    

    La syntaxe varie un peu entre les bases de données, SQL Le serveur utilise '1', alors que pour Postgres, il utilise juste 1. Mais l'intention est la même. Le résultat net est que cela vous coûtera un coup supplémentaire de DB chaque fois que vous essayerez d'obtenir une connexion, mais c'est un coup très, vraiment bon marché. Mais encore, c'est un succès.

    Mais vous pouvez implémenter votre propre version. Il pourrait faire le contrôle, disons, toutes les 10 demandes, ou même moins fréquemment. Rouler un nombre aléatoire de 1 à N (N = 10, 20, 100 ...), si vous obtenez un '1', faites le select (et échouez, si cela échoue), sinon retournez "true". Mais en même temps, configurez-le de sorte que si vous détectez une erreur, purgez tout le pool. Ajustez clairement ceci de sorte que vous ayez une bonne chance que cela se produise quand votre db descend la nuit (pas combien votre système est occupé la nuit) par rapport au traitement de pointe.

    Vous pourriez même "réduire les probabilités" pendant le traitement de pointe. "si temps entre 6h et 18h alors chance = 1000 chances supplémentaires = 100; si (aléatoire (chances) == 1) {sélectionnez ...}"

    Une option aléatoire supprime la nécessité de maintenir un compteur de sécurité . En fin de compte, cela n'a pas vraiment d'importance, vous voulez juste une note en temps opportun que la base de données est en panne afin que vous puissiez demander à GF d'abandonner le pool.

    Je peux certainement le voir se débattre un peu au tout début lorsque la DB se lève, peut-être rafraichir la piscine plus d'une fois, mais cela devrait être inoffensif.

    Différentes façons de jouer avec ça, mais c'est une piste à considérer.

    Questions connexes