Comment mettre en place des opérations pour les deux applications Web et des travaux par lots en utilisant Spring et Hibernate

StackOverflow https://stackoverflow.com/questions/3882994

Question

I ai une application qui utilise Spring 2.5 et Hibernate 3.

Il y a une application web avec une couche de présentation, une couche servive et une couche de DAO, ainsi que des emplois de quartz qui partagent les mêmes couches de services et DAO.

Les transactions sont initialisés dans les différentes couches avec annotations @Transactional, comme ceci:

text alt

Il me conduit à un problème que je décrit ici: Le contrôle des paramètres de transaction interne de transaction externe avec Spring 2.5

J'ai lu un peu sur la façon dont les opérations de mise en place au fil de Spring et Hibernate ensemble. Il semble l'approche recommandée est d'initialiser les transactions dans la couche de service.

Ce que je ne aime pas est que la plupart des transactions existent seulement parce qu'ils sont nécessaires pour mise en veille prolongée pour fonctionner correctement.

Et quand je vraiment besoin d'une opération pour un emploi appelant plusieurs méthodes de service, il semble que je n'ai pas le choix de garder l'initialisation des transactions des emplois. Ainsi, le déplacement des annotations @Transactional de DAO vers le service ne semble pas faire de différence.

Comment recommanderiez-vous à des opérations de mise en place pour ce type d'application?

Était-ce utile?

La solution

  

J'ai lu un peu sur la façon dont les opérations de mise en place au fil de Spring et Hibernate ensemble. Il semble l'approche recommandée est d'initialiser les transactions dans la couche de service.

Certainement. La démarcation des transactions doit être effectuée au niveau de la couche de service, et non au niveau de la couche DAO:

  • l'unité de travail est le service, pas le DAO
  • vous voulez une transaction à étendre sur plusieurs OTI si nécessaire.
  

Ce que je ne aime pas est que la plupart des transactions existent seulement parce qu'ils sont nécessaires pour mise en veille prolongée pour fonctionner correctement.

Vous devriez peut-être élaborer cette partie parce que les transactions ne sont pas spécifiques Hibernate.

  

Et quand je vraiment besoin d'une opération pour un emploi appelant plusieurs méthodes de service, il semble que je n'ai pas le choix de garder l'initialisation des transactions des emplois.

Si vous voulez appeler plusieurs services dans une transaction initiée à partir de la couche d'emploi, déclarer vos services transactionnels avec REQUIRED sémantique (par défaut) et repose sur la propagation des transactions Spring (valable sauf si vous avez besoin d'un appel à distance, dans ce cas, utilisation). EJBs

  

déplacer les annotations @Transactional de DAO vers le service ne semble pas faire de différence.

fait faire une différence et le fait que vous devez effectuer des transactions de la couche d'emploi lors de l'exécution des lots ne fait pas des choses différentes.

Je recommande vivement de lire le Chapitre 9. Gestion des transactions .


  

(...) mon principal problème vient de Mise en veille prolongée. Désolé si je n'étais pas claire.

Pas de problème. Il est juste que, lorsqu'une question est vague, vous obtenez souvent une réponse vague:)

  

De la documentation mise en veille prolongée: « les transactions de base de données ne sont jamais optionnelles Toutes les communications avec une base de données doit se produire dans une transaction... » C'est pourquoi les développeurs ont mis les méthodes de DAO transactionnel sur mon projet.

Désolé, mais la déclaration ci-dessus dit seulement que le « communication avec une base de données doit se produire dans une transaction » , rien de plus, et de décider où commencer la transaction est laissée à votre discrétion (généralement la couche de service). Si vous le faites au niveau DAO, si les appels MySuperService DaoFoo et DaoBar et DaoBar échoue? Dans ce cas, vous aurez probablement envie de rollback tous les changements, non seulement celles effectuées dans DaoBar. D'où la nécessité de transaction de contrôle où l'unité de travail commence.

à mon humble avis, les développeurs ont besoin de conseils.

  

Est-ce que cela veut dire tous mes services devrait être transactionnel? Même quand je viens de lire les données par exemple?

Tout d'abord, je vous suggère de lire accès aux données non transactionnelles et l'auto-validation le mode (le petit frère de Sessions et transactions ) pour clarifier les choses au sujet de "transactions en lecture seule" . La lecture de la page entière est la peine, mais permettez-moi de citer simplement cette partie spécifique:

  

De nombreux développeurs d'applications pensent qu'ils   peut parler à un extérieur d'une base de données   transaction. Ceci est évidemment pas   possible; aucune instruction SQL peut être envoyer   une base de données en dehors d'une base de données   transaction . Le terme non transactionnelles   des moyens d'accès aux données il n'y a pas   explicites limites de transaction, pas   système transaction, et que le   le comportement d'accès aux données est celle de la   mode de validation automatique. Cela ne signifie pas non   les transactions de base de données physiques   impliqués.

Une fois que vous aurez terminé avec le lien ci-dessus, la lecture suivante sera proposée @ transactionnelles en lecture seule pièges drapeau . Voici la partie pertinente:

  

(...) La ligne de fond est que lorsque vous   utiliser un cadre fondé sur ORM, la   lecture seule drapeau est tout à fait inutile et   la plupart des cas est ignoré. Mais si tu   persistons à l'utiliser, réglez toujours   le mode de propagation à des supports, comme   dans le Listing 9, donc pas de transaction   est commencé:

     

Liste 9. Utilisation en lecture seule et le mode de propagation de SUPPORTS pour select   opération

@Transactional(readOnly = true, propagation=Propagation.SUPPORTS)
public TradeData getTrade(long tradeId) throws Exception {
   return em.find(TradeData.class, tradeId);
}
     

Mieux encore, évitez tout en utilisant la   annotation @Transactional tout à fait   lorsque vous effectuez des opérations de lecture, comme le montre   dans le Listing 10:

     

Listing 10. Retrait de l'annotation @Transactional pour select   opérations

public TradeData getTrade(long tradeId) throws Exception {
   return em.find(TradeData.class, tradeId);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top