web-dev-qa-db-fra.com

Le fil de session d'Hibernate est-il sécurisé?

J'ai besoin de savoir si la session d'Hibernate est thread-safe ou non. Mais il est évident qu'une nouvelle session est attachée à chaque thread pour l'exécution. Mais ma question est de savoir si dans un thread j'ai mis à jour une valeur d'une entité, cela sera-t-il reflété dans un autre thread lors de la même exécution?

Mon problème est que lorsque je lance la mise à jour à partir de deux threads de manière séquentielle, la valeur est mise à jour correctement, mais lorsque je lance la mise à jour presque complètement, elle échoue.

pour par exemple. stade actuel de la table.

  ID      NAME      MARKS
------- --------- --------
  1       John       54

J'essaie de faire ce qui suit:

Student student = session.load(Student.class, 1);
student.setMarks(student.getMarks() + 1);
session.update(student);
session.close();

Lorsque j'essaie d'exécuter le code ci-dessus en boucle, dites 10, la valeur de "marques" dans le tableau "étudiant" est correctement mise à jour, c'est-à-dire que la valeur est mise à jour à 64, ce qui est correct.

Mais lorsque j'essaie d'exécuter le même code dans un environnement threadé, les résultats sont mauvais.

16
M.J.

Les implémenteurs ne doivent pas être threadsafe. Au lieu de cela, chaque thread/transaction doit obtenir sa propre instance à partir d'une SessionFactory.

Même dans cet esprit, votre comportement pourrait ne pas être conforme à vos attentes, car les transactions entrent en jeu. Vous devrez définir un niveau d'isolement transaction correct . Voir le configuration guide , hibernate.connection.isolation.

18
Bozho

La session Hibernate et les threads ne se mélangent pas.

Vous ne devez pas utiliser une session à partir de plusieurs threads en même temps, et je vous recommande de n'utiliser qu'une session à partir d'un seul thread. Les implémentations de session de base de données n'ont même pas besoin d'être theadsafe.

Vous devez également tenir compte de ce qu'il advient des transactions lorsque vous commencez à faire des choses dans plusieurs threads. Les transactions sont liées au fil actuel. Cela devient rapidement époustouflant et vous entrez dans des zones où les développeurs n'ont pas testé leurs produits.

En fin de compte, la vie est trop courte pour se perdre dans ce marais.

17
Peter Tillemans

Les sessions Hibernate ne sont pas thread-safe. Utilisez la classe TheadLocal pour créer des sessions pour chaque thread: -

 private static ThreadLocal<Session> threadSafeSession = new ThreadLocal<Session>() {
    protected Session initialValue(){
    return sf.openSession();
      }
    };

Dans votre méthode, obtenez une session pour chaque thread en tant que: -

Session session = threadSafeSession.get();
4
Goyal Vicky

Cela dépend de la façon dont vous créez une session.

La session peut être créée de deux manières en veille prolongée. 

  1. getCurrentSession ()

Oui. Il offre la sécurité des threads car cela garantira la création d'une session pour chaque thread si la session n'existe pas. la transaction et la fermeture automatique de session sont attachées à cela.

  1. openSession ()

Ce n'est pas thread-safe. Le développeur doit manuellement gérer les transactions et les opérations de vidage et de fermeture de session.

2
Sumanth Varada

L'objet Session a été conçu pour être utilisé par un seul thread. En interne, la session utilise de nombreuses structures de données non thread-safe, il est donc impossible de la rendre thread-safe.

De plus, vous ne devriez même pas avoir besoin d’utiliser une session thread-safe. Si votre cas d'utilisation consiste à partager les entités mises en cache, vous devez utiliser le cache de second niveau, qui est thread-safe et peut être utilisé dans un environnement en cluster.

Cela étant dit, la nécessité d'avoir une session thread-safe est une odeur de code indiquant une faille dans la conception de la couche d'accès aux données.

0
Vicky