javax.transaction.Transactional vs org.springframework.transaction.annotation.Transactional

153

Je ne comprends pas quelle est la différence réelle entre les annotations javax.transaction.Transactionalet org.springframework.transaction.annotation.Transactional?

Est-ce org.springframework.transaction.annotation.Transactionalune extension de javax.transaction.Transactionalou ont-ils une signification totalement différente? Quand faut-il utiliser chacun d'eux? Spring @Transactinaldans la couche de service et javax dans DAO?

Merci de répondre.

stamis
la source

Réponses:

125

Spring a défini sa propre annotation transactionnelle pour rendre les méthodes Spring Bean transactionnelles, il y a des années.

Java EE 7 a finalement fait la même chose et permet désormais aux méthodes bean CDI d'être transactionnelles, en plus des méthodes EJB. Donc depuis Java EE 7, il définit également sa propre annotation Transactionnelle (il ne peut évidemment pas réutiliser celui de Spring).

Dans une application Java EE 7, vous utiliserez l'annotation Java EE.

Dans une application Spring, vous utiliserez l'annotation Spring.

Leur utilisation est la même: informer le conteneur (Java EE ou Spring) qu'une méthode est transactionnelle.

JB Nizet
la source
28
Plus que cela: afin de gouverner l'univers, Spring a également ajouté un support implicite pour javax.transaction.Transactionalque l'on puisse désormais l'utiliser également dans les applications Spring sans aucune action supplémentaire. OMI, c'était une très mauvaise décision du point de vue de la conception , car d'après mon expérience, beaucoup de développeurs confondent inconsciemment ces deux dans leur code, ce qui entraîne des problèmes par la suite.
Yuriy Nakonechnyy
16
De plus, org.springframework.transaction.annotation.Transactionaloffre plus d'options (comme readOnly, timeout) quejavax.transaction.Transactional
pierrefevrier
1
@yura, quels problèmes avez-vous observés?
Lee Chee Kiam
1
@LeeCheeKiam s'il vous plaît voir deux réponses ci
Yuriy Nakonechnyy
50

Une autre différence est la façon dont Spring gère les annotations @Transactional

  • org.springframework.transaction.annotation.Transactional est toujours pris en compte
  • javax.transaction.Transactional n'est pris en compte que lorsque des transactions EJB3 sont présentes. La présence des transactions EJB3 se fait en vérifiant si la classe javax.ejb.TransactionAttributeest disponible dans le chemin des classes (de la version 2.5.3 à 3.2.5). Ainsi, vous pouvez vous retrouver avec vos annotations non prises en compte si ce n'est que javax.transaction.Transactionaldans votre chemin de classe et non javax.ejb.TransactionAttribute. Cela peut être le cas si vous travaillez avec Hibernate: hibernate-core (4.3.7.Final) dépend de jboss-transaction-api_1.2_spec (1.0.0.Final), qui ne fournit pas javax.ejb.TransactionAttribute.
Jidehem
la source
ce n'est pas toujours pris, si c'est sur une méthode privée par exemple, il ne sera pas pris.
strash du
36

Veuillez faire attention, (ce problème est survenu dans tomcat),

Si votre application est une application Web SPRING et que vous utilisez le mécanisme de gestion des transactions de Spring @org.springframework.transaction.annotation.Transactional, ne le mélangez pas avec javax.transaction.Transactional.

C'est toujours utiliser, @org.springframework.transaction.annotation.Transactional dans une application de printemps de manière cohérente.

Sinon, nous pouvons nous retrouver avec cette erreur,

org.springframework.orm.jpa.JpaSystemException: commit failed; nested exception is org.hibernate.TransactionException: commit failed

........

Caused by: java.sql.SQLException: Protocol violation: [0]
Lyju I Edwinson
la source
1
Remarque: cette réponse est un cas particulier de ma réponse
Jidehem
3

Périmètre de transaction déclarative

Les @Transactionannotations Spring et JPA vous permettent de définir la portée d'une transaction d'application donnée.

Ainsi, si une méthode de service est annotée avec le @Transactional annotation, elle s'exécutera dans un contexte transactionnel. Si la méthode de service utilise plusieurs DAO ou référentiels, toutes les opérations de lecture et d'écriture seront exécutées dans la même transaction de base de données.

Printemps @Transactional

L' org.springframework.transaction.annotation.Transactionalannotation est disponible depuis la version 1.2 du framework Spring (vers 2005) et vous permet de définir les propriétés transactionnelles suivantes:

  • isolation: le niveau d'isolement de la base de données sous-jacente
  • noRollbackForet noRollbackForClassName: la liste des Exceptionclasses Java pouvant être déclenchées sans déclencher une annulation de transaction
  • rollbackForet rollbackForClassName: la liste des Exceptionclasses Java qui déclenchent une annulation de transaction lors de la levée
  • propagation: le type de propagation de transaction donné par PropagationEnum. Par exemple, si le contexte de transaction peut être hérité (par exemple, REQUIRED) ou si un nouveau contexte de transaction doit être créé (par exemple, REQUIRES_NEW) ou si une exception doit être levée si aucun contexte de transaction n'est présent (par exemple, MANDATORY) ou si une exception doit être levée si un contexte de transaction courant est trouvé (par exemple, NOT_SUPPORTED).
  • readOnly: si la transaction en cours doit uniquement lire les données sans appliquer de modifications.
  • timeout: combien de secondes le contexte de transaction doit-il être autorisé à s'exécuter jusqu'à ce qu'une exception de délai d'attente soit levée.
  • valueou transactionManager: le nom du TransactionManagerbean Spring à utiliser lors de la liaison du contexte de transaction.

Java EE @Transactional

L' javax.transaction.Transactionalannotation a été ajoutée par la spécification Java EE 7 (vers 2013). Ainsi, l'annotation Java EE a été ajoutée 8 ans plus tard que son homologue Spring.

Java EE ne @Transactionaldéfinit que 3 attributs:

  • dontRollbackOn: la liste des Exceptionclasses Java qui peuvent être déclenchées sans déclencher un rollback de transaction
  • rollbackOn: la liste des Exceptionclasses Java qui déclenchent un rollback de transaction lors de la levée
  • value: la stratégie de propagation, donnée par TxTypeEnum. Par exemple, si le contexte de transaction peut être hérité (par exemple, REQUIRED) ou si un nouveau contexte de transaction doit être créé (par exemple, REQUIRES_NEW) ou si une exception doit être levée si aucun contexte de transaction n'est présent (par exemple, MANDATORY) ou si une exception doit être levée si un contexte de transaction courant est trouvé (par exemple, NOT_SUPPORTED).

Lequel choisir?

Si vous utilisez Spring ou Spring Boot, utilisez l' @Transactionalannotation Spring , car elle vous permet de configurer plus d'attributs que l' @Transactionalannotation Java EE .

Si vous utilisez Java EE seul et que vous déployez votre application sur un serveur d'applications Java EE, utilisez l'annotation Java EE `` @ Transactional`.

Pour plus d'informations sur les différences de configuration du niveau d'isolement lors de l'utilisation des @Transactionaldéfinitions Spring ou Java EE , consultez cet article .

Vlad Mihalcea
la source