web-dev-qa-db-fra.com

Contrôler la session de veille prolongée (quand la fermer manuellement)

Je suis nouveau en veille prolongée, après avoir lu l’API et le tutoriel relatifs à la veille prolongée, il semble que la session devrait être fermée quand elle n’est pas utilisée.

Comme ça:

Session sess=getSession();
Transcration tx=sess.beginTranscration();
//do something using teh session
sess.save(obj);
tx.commit();
sess.close;

Je n'ai aucune question lorsque je l'utilise dans une application autonome . Cependant, je ne suis pas sûr d'utiliser cette application Web.

Par exemple, j'ai un servlet: TestServlet pour recevoir les paramètres du client, puis j'appelle un gestionnaire pour interroger quelque chose en fonction des paramètres, comme ceci:

class TestServlet{
  doGet(HttpServletRequset,httpServletResponse){
    String para1=request.getParam...();
    String para2=.....
    new Manager().query(para1,para2);
  }
}

class Manager{
  public String query(String pa1,String pa2){
    Session=....// get the session
    //do query using para1 and 1
    session.close() //Here, I wonder if I should close it.
  }
}

Dois-je fermer la session dans la méthode de requête?

Depuis que quelqu'un m'a dit que la session en veille prolongée est juste comme la connexion en jdbc. Donc, ouvrir et fermer si souvent est la bonne façon?

BTW, est-ce que tx.commit () est requis à chaque fois?

Aussi, quel est le problème de thread à propos de l'utilisation de session dans servlet, puisque j'ai vu que la session n'est pas thread-safe dans api.

61
hguser

Je suis nouveau en veille prolongée, après avoir lu l’API en veille prolongée et le didacticiel, il semble que la session devrait s’écrouler sans être utilisée.

Il devrait être fermé lorsque vous avez terminé (mais cela peut être fait automatiquement pour vous comme nous le verrons).

Je n'ai aucune question lorsque je l'utilise dans une application autonome. Cependant, je ne suis pas sûr lors de l'utilisation de l'application Web.

Eh bien, comme expliqué dans la section 11.1.1. Unité de travail de la documentation, le le plus commun Le modèle dans une application client/serveur multi-utilisateurs est session par requête .

Par exemple, j'ai un servlet: TestServlet pour recevoir les paramètres du client, puis j'appelle un gestionnaire pour interroger quelque chose en fonction des paramètres: comme ceci (...) Dois-je fermer la session dans la méthode de requête?

Tout dépend de la façon dont vous obtenez la session.

  • si vous utilisez sessionFactory.getCurrentSession(), vous obtiendrez une "session en cours" liée au cycle de vie de la transaction. Elle sera automatiquement vidée et fermée à la fin de la transaction (validation ou annulation).
  • si vous décidez d'utiliser sessionFactory.openSession(), vous devrez gérer la session vous-même, puis la vider et la fermer "manuellement".

Pour implémenter un modèle session par requête , préférez la première approche (beaucoup plus facile et moins détaillée). Utilisez la deuxième approche pour implémenter de longues conversations .

La page wiki Sessions et transactions est un bon complément à la documentation sur ce sujet.

BTW, est-ce que tx.commit () est requis à chaque fois?

Vous voudrez peut-être lire Accès aux données non transactionnelles et mode d’auto-validation pour clarifier quelques points, mais, pour le dire simplement, votre code Hibernate doit être exécuté dans une transaction et je suggère utiliser des limites de transaction explicites (ie beginTransaction et commit explicites).

Aussi, quel est le problème de thread à propos de l'utilisation de session dans servlet, puisque j'ai vu que la session n'est pas thread-safe dans api.

Il suffit de ne pas en faire une variable d'instance du Servlet et vous n'aurez aucun problème.

Références

114
Pascal Thivent

Une session est ouverte chaque fois que getCurrentSession() est appelée pour la première fois et fermée à la fin de la transaction.

Cela crée une toute nouvelle session s'il n'en existe pas ou utilise une session existante s'il en existe déjà une. Il est automatiquement configuré avec les attributs de vidage automatique et de fermeture automatique car vrai signifie que Session sera automatiquement vidé et fermé.

Si vous utilisez getCurrentSession() alors pas besoin de fermer la connexion si vous allez essayer cela, vous ferez face à une exception.

0
Virendra khade

Si vous obtenez une session avec sessionFactory.openSession(), vous devez la fermer en externe . Une session ouverte pendant une période non souhaitée peut provoquer des fuites de données. De plus, il peut donner une invitation à la menace de sécurité de l'application Web.

0
user6069813

Nous pouvons utiliser ThreadLocal.

public class MyUtil {
private static SessionFactory sessionFactory;
private static ServiceRegistry serviceRegistry;
private static final ThreadLocal<Session> threadLocal;

static {
try {
    Configuration configuration = new Configuration();
    configuration.configure();
    serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
    sessionFactory = configuration.buildSessionFactory(serviceRegistry);
    threadLocal = new ThreadLocal<Session>();

    } catch(Throwable t){
      t.printStackTrace();
      throw new ExceptionInInitializerError(t);
    }
}
public static Session getSession() {
    Session session = threadLocal.get();
    if(session == null){
        session = sessionFactory.openSession();
        threadLocal.set(session);
    }
    return session;
}

public static void closeSession() {
    Session session = threadLocal.get();
    if(session != null){
    session.close();
    threadLocal.set(null);
    }
}

public static void closeSessionFactory() {
    sessionFactory.close();
    StandardServiceRegistryBuilder.destroy(serviceRegistry);
   }
}

Ici, la variable SessionFactory n'est initialisée qu'une seule fois à l'aide du bloc statique. Par conséquent, chaque fois que la classe main appelle la fonction getSession(), la présence de l'objet Session est d'abord vérifiée dans l'objet threadLocal . Par conséquent, ce programme fournit thread-safety . Après chaque opération, closeSession() ferme la session et définissez l'objet threadLocal sur null . Enfin, appelez la closeSessionFactory().

0
AnirbanDebnath