Question Où l'annotation @Transactional appartient-elle?


Si vous placez le @Transactional dans le DAO classes et / ou leurs méthodes ou est-il préférable d'annoter les classes de service qui appellent en utilisant les objets DAO? Ou est-il judicieux d’annoter les deux "couches"?


441
2017-07-03 12:20


origine


Réponses:


Je pense que les transactions appartiennent à la couche Service. C'est celui qui connaît les unités de travail et les cas d'utilisation. C'est la bonne réponse si vous avez plusieurs DAO injectés dans un service qui doivent travailler ensemble dans une seule transaction.


456
2017-07-03 12:23



En général, je suis d’accord avec les autres déclarant que les transactions sont généralement lancées au niveau du service (en fonction de la granularité dont vous avez besoin, bien sûr).

Cependant, en attendant, j'ai aussi commencé à ajouter @Transactional(propagation = Propagation.MANDATORY) à ma couche DAO (et à d'autres couches qui ne sont pas autorisées à démarrer des transactions mais qui en ont besoin) car il est beaucoup plus facile de détecter des erreurs lorsque vous avez oublié de démarrer une transaction dans l'appelant (par exemple le service). Si votre DAO est annoté avec une propagation obligatoire, vous obtiendrez une exception indiquant qu'il n'y a pas de transaction active lorsque la méthode est appelée.

J'ai aussi un test d'intégration où je vérifie tous les beans (bean post processor) pour cette annotation et échoue s'il y a un @Transactional annotation avec propagation autre que Obligatoire dans un bean qui n'appartient pas à la couche services. De cette façon, je m'assure de ne pas lancer de transactions sur la mauvaise couche.


266
2017-08-30 06:50



Les annotations transactionnelles doivent être placées autour de toutes les opérations inséparables.

Par exemple, votre appel est "changer le mot de passe". Cela consiste en deux opérations

  1. Changer le mot de passe
  2. Auditer le changement.
  3. Envoyez un e-mail au client pour lui indiquer que le mot de passe a changé.

Donc, dans ce qui précède, si l'audit échoue, alors le changement de mot de passe doit également échouer? Si oui, alors la transaction devrait être autour de 1 et 2 (donc à la couche de service). Si le courrier électronique échoue (il devrait probablement y avoir une sorte de protection contre les pannes pour qu'il n'échoue pas), alors devrait-il annuler le mot de passe de modification et l'audit?

Ce sont le genre de questions que vous devez poser lorsque vous décidez où placer la @Transactional.


76
2017-07-07 13:46



Le cas normal serait d'annoter au niveau de la couche de service, mais cela dépend vraiment de vos besoins.

L'annotation sur une couche de service entraînera des transactions plus longues que l'annotation au niveau DAO. Selon le niveau d'isolation de la transaction qui peut générer des problèmes, car les transactions concurrentes ne verront pas les modifications de l'autre, par exemple. LECTURE RÉPÉTABLE.

Les annotations sur les DAO maintiendront les transactions aussi courtes que possible, l'inconvénient étant que la fonctionnalité exposée par votre couche de service ne sera pas effectuée dans une transaction unique (pouvant être annulée).

Cela n'a aucun sens d'annoter les deux couches si le mode de propagation est défini sur la valeur par défaut.


37
2017-07-03 12:34



La réponse correcte pour les architectures Spring traditionnelles consiste à placer la sémantique transactionnelle dans les classes de service, pour les raisons que d'autres ont déjà décrites.

Une tendance émergente au printemps est vers conception pilotée par le domaine (DDD). Roo du printemps illustre bien la tendance. L'idée est de faire beaucoup de choses sur l'objet de domaine POJOs plus riche qu'ils ne le sont sur les architectures de printemps typiques (généralement ils sont anémique), et en particulier pour placer la sémantique de transaction et de persistance sur les objets du domaine eux-mêmes. Dans les cas où il suffit d'opérations CRUD simples, les contrôleurs Web fonctionnent directement sur les objets POJO de l'objet de domaine (ils fonctionnent comme des entités dans ce contexte) et il n'y a pas de niveau de service. Dans les cas où il existe une sorte de coordination nécessaire entre les objets du domaine, vous pouvez avoir un handle de bean de service qui, avec @Transaction selon la tradition. Vous pouvez définir la propagation de la transaction sur les objets de domaine à quelque chose comme REQUIRED afin que les objets de domaine utilisent toutes les transactions existantes, telles que les transactions qui ont été démarrées sur le bean de service.

Techniquement, cette technique utilise AspectJ et <context:spring-configured />. Roo utilise les définitions inter-types AspectJ pour séparer la sémantique de l'entité (transactions et persistance) des éléments de l'objet de domaine (essentiellement des champs et des méthodes métier).


37
2017-07-31 19:52



Je place le @Transactional sur le @Service couche et ensemble rollbackFor toute exception et readOnly optimiser davantage la transaction.

Par défaut @Transactional ne cherchera que RuntimeException (Exceptions non contrôlées), en définissant l'annulation Exception.class (Exceptions vérifiées) il reviendra pour toute exception.

@Transactional(readOnly = false, rollbackFor = Exception.class)

Voir Exceptions vérifiées et non vérifiées.


28
2017-07-24 00:10



Ou est-il judicieux d’annoter les deux "couches"? - cela n'a-t-il pas de sens d'annoter à la fois la couche service et la couche dao - si l'on veut s'assurer que la méthode DAO est toujours appelée (propagée) à partir d'une couche service avec propagation "obligatoire" dans DAO. Cela fournirait une restriction pour que les méthodes DAO soient appelées à partir de la couche d'interface utilisateur (ou des contrôleurs). En outre, lorsque l'unité teste la couche DAO en particulier, le fait que DAO soit annoté garantira également son test de fonctionnalité transactionnelle.


17
2018-05-25 11:54



En outre, Spring recommande d'utiliser uniquement l'annotation sur les classes concrètes et non sur les interfaces.

http://static.springsource.org/spring/docs/2.0.x/reference/transaction.html


15
2018-01-12 15:57