Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1392 connectés 

  FORUM HardWare.fr
  Programmation
  Java

  Problème variable static - application web tomcat

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Problème variable static - application web tomcat

n°1568680
Djebel1
Nul professionnel
Posté le 01-06-2007 à 15:24:00  profilanswer
 

Hello,  
 
j'ai un pti souci en développant une appli web tournant sur tomcat.
 
J'utilise un singleton pour tout ce qui est accès à la base de données, il existe donc une variable statique qui stock le singleton une fois instancié. Voilà le problème : je viens du PHP (me tapez pas), et une variable statique n'est pas partagée entre les différents utilisateurs : chaque utilisateur a donc "son" singleton d'accès à la base.
 
Sous tomcat, les variables statiques sont partagées pour tous les utilisateurs. J'imagine qu'il y a un moyen pour rendre ces variables uniques pour chaque session utilisateur, mais je ne sais pas trop comment faire de manière simple. Vous pourriez m'orienter svp ? :)

mood
Publicité
Posté le 01-06-2007 à 15:24:00  profilanswer
 

n°1568875
Cherrytree
cn=?
Posté le 02-06-2007 à 00:07:11  profilanswer
 

Ce n'est pas une variable static qu'il te faut.
 
Si tu cherches à avoir un objet par session d'utilisateur, tu fais :
 

Code :
  1. HttpSession session = request.getSession();
  2. session.setAttribute("anyName", anyObject); // pour sauvegarder l'objet en session
  3. Object o = session.get("anyName" ); // pour récupérer l'objet en session


 
request est ici une variable de type HttpServletRequest, donc selon comment et avec quoi tu développes, ce code est à placer dans une Action, un Servlet, une JSP...
 
Par contre, je questionne le fait de mettre un objet lié à l'accès au données en session. Je ne connais pas le détail, mais pour des questions d'architecture (n-tiers etc.) j'éviterais de faire ce que je crois comprendre que tu fais.

n°1569059
Djebel1
Nul professionnel
Posté le 02-06-2007 à 16:49:16  profilanswer
 

Clairement pour les raisons d'architecture que tu évoques ça le fait pas trop de mettre l'objet en session. Je voulais plutôt dire "spécifique à chaque utilisateur" que "spécifique à une session".
 
Ce que je souhaiterais, c'est que le singleton soit propre à chaque utilisateur, donc que la variable statique stocke plusieurs objets d'accès à la base, un par utilisateur, que ça soit un peu un "pool" de connections à la base.
 
Mais comment faire ça de manière propre ? Par exemple je pourrai faire remonter un identifiant d'utilisateur jusqu'à la couche d'accès aux données,  mais c'est pas super propre je trouve.
 
Peut-être faut-il que je me tourne vers les threads ? Une variable statique est-elle partagée entre threads ?
 
(je pensais par défaut qu'avec tomcat chaque utilisateur lançait un thread différent, qui ne partageaient pas d'infos entre eux, visiblement je me trompe quelque part ... je pourrais donc éventuellement faire en sorte que chaque requête utilisateur lance un thread différent, mais ... ça marcherait ? :p)

Message cité 1 fois
Message édité par Djebel1 le 02-06-2007 à 16:50:46
n°1569324
phnatomass
Je m'empare de ton esprit !!
Posté le 03-06-2007 à 18:09:19  profilanswer
 

Thread Local Pattern

n°1569726
Djebel1
Nul professionnel
Posté le 04-06-2007 à 14:44:17  profilanswer
 

En cherchant dans google je trouve pas beaucoup de liens explicatifs. Tu pourrais m'en dire plus ou me filer des liens sympas stp ?

n°1572781
Cherrytree
cn=?
Posté le 09-06-2007 à 18:14:22  profilanswer
 

Djebel1 a écrit :

Clairement pour les raisons d'architecture que tu évoques ça le fait pas trop de mettre l'objet en session. Je voulais plutôt dire "spécifique à chaque utilisateur" que "spécifique à une session".
 
Ce que je souhaiterais, c'est que le singleton soit propre à chaque utilisateur, donc que la variable statique stocke plusieurs objets d'accès à la base, un par utilisateur, que ça soit un peu un "pool" de connections à la base.
 
Mais comment faire ça de manière propre ? Par exemple je pourrai faire remonter un identifiant d'utilisateur jusqu'à la couche d'accès aux données,  mais c'est pas super propre je trouve.
 
Peut-être faut-il que je me tourne vers les threads ? Une variable statique est-elle partagée entre threads ?
 
(je pensais par défaut qu'avec tomcat chaque utilisateur lançait un thread différent, qui ne partageaient pas d'infos entre eux, visiblement je me trompe quelque part ... je pourrais donc éventuellement faire en sorte que chaque requête utilisateur lance un thread différent, mais ... ça marcherait ? :p)


 
Personnellement, j'éviterais de trafiquer avec les threads. ça donne des solutions élégantes et courtes, mais difficilement comprises par d'autres ; sans doute à cause du côté "contexte magique", transverse... Je laisse l'argumentation là, n'étant pas expert de ce genre d'implémentation, duquel je m'éloignes autant que possible ; en dépit du côté pratique indéniable.
 
Tel que tu présentes le problème, je me demande si une solution de ce type ne pourrait pas être satisfaisante :

Code :
  1. class Contexts {
  2.     private Map contexts = new HashMap();
  3.     private static Contexts instance;
  4.     public static Contexts getInstance() {
  5.         if (instance == null) instance = new Contexts();
  6.         return instance;
  7.     }
  8.     private Contexts() {}
  9.     public Context getContext(User u) { return (Context) contexts.get(u); }
  10.     ...
  11. }


Il s'agit bien d'un Singleton, qui gère des contextes utilisateur. Il reste à définir ce qu'est un User au sens métier, et un Context au sens de ton application. Un contexte pourrait contenir diverses informations, préférences, etc.
J'étudierais dans quelle mesure utiliser un ID de session HTTP est une bonne / mauvaise clé pour identifier un User, ou si un nom d'utilisateur, numéro de qqch (INSEE, SIREN, FINESS...) est plus approprié.
Pour le contexte, je me poserais la question de la montée en charge : combien d'utilisateurs, combien d'objets dans le contexte, quelle lourdeur en moyenne pour chaque objet, etc.
De façon générale, je me poserais la question de ce qui rends les données propres à un utilisateur.
Ce ne sont que des pistes.


Message édité par Cherrytree le 09-06-2007 à 18:14:53
n°1572783
Cherrytree
cn=?
Posté le 09-06-2007 à 18:23:32  profilanswer
 

Djebel1 a écrit :

En cherchant dans google je trouve pas beaucoup de liens explicatifs. Tu pourrais m'en dire plus ou me filer des liens sympas stp ?


Un cas d'utilisation classique de ThreadLocal avec Hibernate ; présenté à l'origine dans le bouquin Hibernate in Action, qui l'explique en détail. J'ai trouvé ce code à http://www.koders.com/java/fid462B [...] A2D58.aspx.
 

Code :
  1. package org.apache.turbine.util.hibernate;
  2. /*
  3. * Copyright 2001-2004 The Apache Software Foundation.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License" )
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. *     http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. import net.sf.hibernate.HibernateException;
  18. import net.sf.hibernate.JDBCException;
  19. import net.sf.hibernate.Session;
  20. import net.sf.hibernate.SessionFactory;
  21. import org.apache.commons.logging.Log;
  22. import org.apache.commons.logging.LogFactory;
  23. /**
  24. * This class is used to get Hibernate Sessions and may
  25. * also contain methods (in the future) to get DBConnections
  26. * or Transactions from JNDI.
  27. */
  28. public class HibernateUtils
  29. {
  30.     //~ Static fields/initializers =============================================
  31.     public final static String SESSION_FACTORY = "hibernate/sessionFactory";
  32.     public static final ThreadLocal session = new ThreadLocal();
  33.     private static SessionFactory sf = null;
  34.     private static HibernateUtils me;
  35.     private static Log log = LogFactory.getLog(HibernateUtils.class);
  36.     static {
  37.         try
  38.         {
  39.             me = new HibernateUtils();
  40.         }
  41.         catch (Exception e)
  42.         {
  43.             log.fatal("Error occurred initializing HibernateUtils" );
  44.             e.printStackTrace();
  45.         }
  46.     }
  47.     //~ Constructors ===========================================================
  48.     private HibernateUtils() throws HibernateException, JDBCException
  49.     {}
  50.     //~ Methods ================================================================
  51.     public static Session currentSession() throws PersistenceException
  52.     {
  53.         Session s = (Session) session.get();
  54.         if (s == null)
  55.         {
  56.             s = PersistenceManager.openSession();
  57.             if (log.isDebugEnabled())
  58.             {
  59.                 log.debug("Opened hibernate session." );
  60.             }
  61.             session.set(s);
  62.         }
  63.         return s;
  64.     }
  65.     public static void closeSession() throws HibernateException, JDBCException
  66.     {
  67.         Session s = (Session) session.get();
  68.         session.set(null);
  69.         if (s != null)
  70.         {
  71.             if (s.isOpen())
  72.             {
  73.                 s.flush();
  74.                 s.close();
  75.                 if (log.isDebugEnabled())
  76.                 {
  77.                     log.debug("Closed hibernate session." );
  78.                 }
  79.             }
  80.         }
  81.         else
  82.         {
  83.             log.warn("Hibernate session was inadvertently already closed." );
  84.         }
  85.     }
  86. }


Le concept est là, bien présent, mais il est dommage que le développeur ait nommé son ThreadLocal "session", que l'on confond volontiers avec le type Session également manipulé par la classe HibernateUtils.

n°1574807
Djebel1
Nul professionnel
Posté le 14-06-2007 à 11:31:59  profilanswer
 

merci pour ces réponses :)
 
Les deux solutions que tu proposes pourraient convenir, je vais voir ce qui m'arrange le plus, je reviens t'embêter au cas si j'ai un souci ^^


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Java

  Problème variable static - application web tomcat

 

Sujets relatifs
recuperation resultat dans variable[ORACLE] Problème execution requête SELECT
Problème de sécurité (accès à une section admin)Probleme vérification
probleme web serviceProblème de Makefile [Résolu]
[VBA / ACCESS] Problème liste déroulante avec autre liste déroulanteRessource id#3 / Undefined variable
Problème avec le contenu d'un fichier[Résolu] Problème avec Firefox
Plus de sujets relatifs à : Problème variable static - application web tomcat


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR