J'utilise une session de mise en veille prolongée par modèle de demande pour mon application Web. Ma transaction jdbc commence au début de chaque requête Web et est validée à la fin.hibernate plusieurs threads empêchent plusieurs sauvegarder(), JTA nécessaire?
// environnement non géré idiome
Session sess = factory.openSession();
Transaction tx = null;
try {
tx = sess.beginTransaction();
// do some work
...
tx.commit();
}
catch (RuntimeException e) {
if (tx != null) tx.rollback();
throw e; // or display error message
}
finally {
sess.close();
}
Je suis confronté au problème où je teste l'existence d'une entité (A) en fonction de plusieurs paramètres et de faire un insert que si elle n » t existe.
public synchronized myMethod(param1, param2) {
MyEntityA entity = MyEntityADAO.findEntity(param1, param2)
if (entity == null) {
entity = .../create entity
MyEntityADAO.save(entity);
}
}
le problème est que la synchronisation ne permet pas parce que l'appel à MyEntityADAO.save() ne pas écrire en fait à la base de données lorsque le thread en cours d'exécution sort de la méthode et libère le verrou, l'écriture à la base de données se produit après la transaction est engagée ce qui est généralement ce dont j'ai besoin pour mon application, sauf pour quelques scénarios. Le code ci-dessus provoque plusieurs enregistrements enregistrés avec les mêmes paramètres dans un environnement multithread.
J'ai essayé d'exécuter le code enregistrer dans sa nouvelle session et de transaction:
public synchronized myMethod(param1, param2) {
MyEntityA entity = MyEntityADAO.findEntity(param1, param2)
if (entity == null) {
entity = .../create entity
Session session = HibernateUtil.createSession();
MyEntityADAO.save(entity);
Transaction t = session.beginTransaction();
}
}
les causes ci-dessus problèmes avec 2 sessions ouvertes chargement de la même collection avec mise en veille prolongée dans certains cas.
Devrais-je inclure chaque appel DAO dans sa propre transaction et utiliser la propagation de transaction avec JTA? Y a-t-il un moyen d'éviter JTA? Est-il possible de valider une transaction associée à la session principale après l'appel de MyEntityADAO.save() et d'appeler beginTransaction sur la session principale juste après et d'avoir la transaction validée à la fin de la requête comme c'est le cas maintenant?
merci de votre contribution. J'ai les contraintes mises en place mais je n'attrape pas les exceptions hibernate/jdbc dans ma couche dao/service. semble être une bonne idée. Je vous remercie. – user979051
J'attrape l'exception ConstraintViolationException et j'essaie d'obtenir l'entité existante dans le bloc de capture et d'obtenir une null..il y a une étape intermédiaire quand la transaction est marquée comme si "terminée" dans la base de données sous-jacente (mysql) et les contraintes de table sont "mis à jour" mais la base de données ne renverra pas encore la nouvelle ligne de la table? – user979051
J'ai essayé de vider la session à la place dans la méthode/bloc synchronisé après la sauvegarde() .. obtenir l'exception moins souvent mais n'a pas encore résolu le problème – user979051