IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Hibernate Java Discussion :

Problème de perf lors d'appel successif d'une proc stocké


Sujet :

Hibernate Java

  1. #1
    Membre habitué

    Inscrit en
    Mai 2005
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 60
    Points : 171
    Points
    171
    Par défaut Problème de perf lors d'appel successif d'une proc stocké
    Bonjour

    Comme mon titre l'indique, j'ai de gros soucis de performances lors d'appels successifs d'une procédure stocké (base Oracle) en Java via Hibernate. Ce soucis de performance était quelque peu redouté car cette proc stockée a 200 paramètres.

    Les premiers appels sont de l'ordre de 3 à 4 secondes au debut puis au bout du 100eme appel successif on commence à atteindre les 15 et + secondes d'exécutions (dût au Garbage Collector qui n'arrive pas a faire le ménage assez vite ?)

    La question est la suivante, avez vous une idée pour optimiser le traitement (en sachant que pour des questions de délais, nous n'avons pas le temps de nous passer de cette proc stockée qui fait un GROS travail métier)
    Je suis preneur de toute proposition.

    PS : il nous est impossible de paralléliser les appel grâce a un pool de Thread car l'ordre d'exécution est significatif.

  2. #2
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    le garbage collector ne sera impliqué que si ta procédure stokée renvoie beaucoup d'informations que tu dois charger en mémoire. As-tu vérifié, avec un client SQL quelconque que ce problème n'est pas lié à la base de donnée (serveur oracle qui mettrait de plus en plus de temps à gérer la procédure stockée en raison de la taillede la transaction qui augmente)?
    Est-ce que des commit réguliers ne peuvent pas résoudre le problème?

    Sinon, si c'est le client java en cause, as-tu essayé des outils de profiling pour trouver les "points chauds" de ton application?

  3. #3
    Membre habitué

    Inscrit en
    Mai 2005
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 60
    Points : 171
    Points
    171
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    le garbage collector ne sera impliqué que si ta procédure stokée renvoie beaucoup d'informations que tu dois charger en mémoire.
    La transtypage de chaque paramètre pour les passer dans un type reconnu par Oracle (chaque paramètre se retrouve donc dédoublé en mémoire et une fois l'appel effectué il faut nettoyer tout ça non ?) n'a pas d'impact ?

    C'est ce point que nous craignons le plus, nous avons peur que le passage de ces 200 paramètres soit la partie longue a éxécuter.

    Faut me dire si je fait erreur, je ne suis pas un spécialiste du fonctionnement de l'appel de PL via Hibernate.

    Citation Envoyé par tchize_ Voir le message
    As-tu vérifié, avec un client SQL quelconque que ce problème n'est pas lié à la base de donnée (serveur oracle qui mettrait de plus en plus de temps à gérer la procédure stockée en raison de la taillede la transaction qui augmente)?
    Est-ce que des commit réguliers ne peuvent pas résoudre le problème?
    Il y a une nouvelle transaction a chaque appel de PL (et donc un commit a chaque fois)

    Citation Envoyé par tchize_ Voir le message
    Sinon, si c'est le client java en cause, as-tu essayé des outils de profiling pour trouver les "points chauds" de ton application?
    C'est prévu, on fait ça cette apres-midi, mais a priori le code Java n'est pas en cause puisque dans une autre partie de l'application, il y a un traitement identique sauf qu'au lieu d'appeller une PL on fait appelle a de l'EJB-QL et dans ce cas ça passe niquel.

  4. #4
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par P4dre Voir le message
    La transtypage de chaque paramètre pour les passer dans un type reconnu par Oracle (chaque paramètre se retrouve donc dédoublé en mémoire et une fois l'appel effectué il faut nettoyer tout ça non ?) n'a pas d'impact ?
    A moins que ce soient 200 blob qui occupent chacun 1M de mémoire, non ca n'a pas d'impact. La JVM effectue la gymnasitque des new / finalize très bien, et 200 objets, c'est des clopinette par rapport à ce qu'elle crée / supprime à chaque seconde.

    [quote]
    Faut me dire si je fait erreur, je ne suis pas un spécialiste du fonctionnement de l'appel de PL via Hibernate.

    Il y a une nouvelle transaction a chaque appel de PL (et donc un commit a chaque fois)
    [QUOTE]
    Normalement, Hibernate effectue une transaction par session hibernate.

    il y a un traitement identique sauf qu'au lieu d'appeller une PL on fait appelle a de l'EJB-QL et dans ce cas ça passe niquel.
    Qu'est-ce que tu appelle "appeler une PL" ? On peux voir le code que tu soupconne responsable?

  5. #5
    Membre habitué

    Inscrit en
    Mai 2005
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 60
    Points : 171
    Points
    171
    Par défaut
    Voici le type de code en cause.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
       CallableStatement stmt = null;
     
        try {
          // création de la connection à la base de données
          Connection connection = getConnection(this.entityManager);
         // le entityManager est un attribut de la classe avec l'anotation @PersistenceContext(unitName = "monUnitName")
     
              // appel de la procédure stockée
              stmt = connection
                  .prepareCall("{ call PAT.RPK_SERV_CCAM.RP_ENREGISTRERACTECCAM(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) }");
     
              //
              // passage des parametres in
              //
     
              if (acte.getCodeActe() != null) {
                stmt.setFloat(1, acte.getCodeActe());
              }
     
              stmt.setString(2, "MCA");
     
             //etc etc... pour tous les paramètres en in et en out

  6. #6
    Membre chevronné
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Points : 1 806
    Points
    1 806
    Par défaut
    J'ai fait des appels de proc-stock à 70 paramètres, et ça passe sans le moindre souci ; alors tu me diras, 70 c'est pas 200, mais ça reste une procédure centrale d'une appli, donc si un problème se posait, ça se verrait quand même un peu. À ta place j'irai aussi fouiller du côté de la procédure en elle-même ; après tout s'il y a 2 appels distincts, c'est qu'il doit y avoir 2 cas distincts ^^

  7. #7
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    tu fais bien une libération de la connection dans un bloc finally? on peux voir ce bloc? De plus tu fais appel à des getters d'objet, peut etre de type hibernate. As-tu vérifié que ces getters sont performants? Certains sont peut etre très lent à s'exécuter (un profiler te dira tout ca rapidement)

  8. #8
    Membre habitué

    Inscrit en
    Mai 2005
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 60
    Points : 171
    Points
    171
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    tu fais bien une libération de la connection dans un bloc finally? on peux voir ce bloc? De plus tu fais appel à des getters d'objet, peut etre de type hibernate. As-tu vérifié que ces getters sont performants? Certains sont peut etre très lent à s'exécuter (un profiler te dira tout ca rapidement)
    Voici le finally :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    finally {
          try {
            if (stmt != null) {
              stmt.close();
            }
          } catch (SQLException exception) {
            throw new MyBusinessException(exception.toString());
          }
        }
    Aucun soucis au niveau des getters. Qui plus est nous avons testé la durée de l'execute de cette façon

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    System.out.println("Avant lancement PL/SQL");
          Long tempsExecution = System.currentTimeMillis();
          stmt.execute();
          tempsExecution = System.currentTimeMillis() - tempsExecution;
          System.out.println("Temps d'exécution du PL/SQL : " + tempsExecution + " Millisecondes");
    Et c'est ici que nous trouvons 4sc d'exécution pour les premiers appel et plus de 15sc d'exécutions a partir du 100eme (et plus) appel consécutif.

  9. #9
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    c'est donc bien au niveau de la requete que se situe le problème. Je ne vois pas de close de ta connection, est-ce normal?? Si tu garde tes connection ouverte et que ton statement manipule beaucoup de row, il est normal qu'a la longue ca devienne difficile pour oracle de gérer tout ça en parallèle.

  10. #10
    Membre expérimenté
    Avatar de Patriarch24
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    1 047
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 047
    Points : 1 640
    Points
    1 640
    Par défaut
    Ce soucis de performance était quelque peu redouté car cette proc stockée a 200 paramètres.
    En premier lieu, utilisez un moteur de recherche.
    En second lieu, postez sur le forum adéquat !

Discussions similaires

  1. Problème d'affichage lors d'appelle d'une méthode
    Par FATENMRABET dans le forum Débuter avec Java
    Réponses: 4
    Dernier message: 03/12/2013, 23h12
  2. Problème blocage lors d'appels successifs a web services
    Par identifiant_bidon dans le forum Services Web
    Réponses: 0
    Dernier message: 04/05/2010, 11h20
  3. Pb lors d'appels successifs d'une subroutine
    Par ClaireA dans le forum Fortran
    Réponses: 4
    Dernier message: 24/11/2009, 14h07
  4. Problème de charset lors de la création d'une instance 8i
    Par girint dans le forum Administration
    Réponses: 2
    Dernier message: 15/06/2007, 13h50
  5. Réponses: 8
    Dernier message: 06/06/2007, 17h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo