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


152

Ich verstehe nicht, was der tatsächliche Unterschied zwischen Anmerkungen javax.transaction.Transactionalund ist org.springframework.transaction.annotation.Transactional.

Ist org.springframework.transaction.annotation.Transactionaleine Erweiterung von javax.transaction.Transactionaloder haben sie eine ganz andere Bedeutung? Wann sollte jeder von ihnen verwendet werden? Frühling @Transactinalin der Serviceschicht und Javax in DAO?

Danke für die Antwort.

Antworten:


125

Spring hat vor Jahren eine eigene Transaktionsanmerkung definiert, um Spring Bean-Methoden transaktional zu machen.

Java EE 7 hat endlich das Gleiche getan und ermöglicht nun zusätzlich zu den EJB-Methoden die Transaktion von CDI-Bean-Methoden. Seit Java EE 7 definiert es auch eine eigene Transaktionsanmerkung (die Spring-Annotation kann offensichtlich nicht wiederverwendet werden).

In einer Java EE 7-Anwendung verwenden Sie die Java EE-Annotation.

In einer Spring-Anwendung verwenden Sie die Spring-Annotation.

Ihre Verwendung ist dieselbe: Informieren des Containers (Java EE oder Spring), dass eine Methode transaktional ist.


28
Mehr als das: Um das Universum zu regieren, fügte Spring auch implizite Unterstützung hinzu, javax.transaction.Transactionalsodass man es jetzt auch in Spring-Anwendungen ohne zusätzliche Aktionen verwenden kann. IMO, dies war vom Design-Standpunkt aus eine ziemlich schlechte Entscheidung , da viele Entwickler meiner Erfahrung nach diese beiden unbewusst in ihrem Code verwechseln, was später zu Problemen führt.
Yuriy Nakonechnyy

16
Darüber hinaus org.springframework.transaction.annotation.Transactionalbietet mehr Optionen (wie readOnly, timeout) alsjavax.transaction.Transactional
pierrefevrier

1
@yura, welche Probleme hast du beobachtet?
Lee Chee Kiam

1
@ LeeCheeKiam bitte sehen Sie zwei Antworten unten
Yuriy Nakonechnyy

50

Ein weiterer Unterschied besteht darin, wie Spring mit den @ Transactional-Annotationen umgeht

  • org.springframework.transaction.annotation.Transactional wird immer berücksichtigt
  • javax.transaction.Transactional wird nur berücksichtigt, wenn EJB3-Transaktionen vorhanden sind. Das Vorhandensein von EJB3-Transaktionen erfolgt durch Überprüfen, ob eine Klasse javax.ejb.TransactionAttributeim Klassenpfad verfügbar ist (von Version 2.5.3 bis 3.2.5). So können Sie dazu führen, dass Ihre Anmerkungen nicht berücksichtigt werden, wenn sie sich nur javax.transaction.Transactionalin Ihrem Klassenpfad befinden und nicht javax.ejb.TransactionAttribute. Dies kann der Fall sein, wenn Sie mit Hibernate arbeiten: Hibernate-Core (4.3.7.Final) hängt von jboss-transaction-api_1.2_spec (1.0.0.Final) ab, das dies nicht bietet javax.ejb.TransactionAttribute.


Es wird nicht immer genommen, wenn es zum Beispiel auf einer privaten Methode ist, wird es nicht genommen.
Strash

36

Bitte seien Sie vorsichtig (dieses Problem ist in Tomcat aufgetreten).

Wenn es sich bei Ihrer Anwendung um eine SPRING-Webanwendung handelt und Sie den Transaktionsbehandlungsmechanismus von Spring verwenden, @org.springframework.transaction.annotation.Transactionalmischen Sie ihn nicht mit javax.transaction.Transactional.

Das ist immer @org.springframework.transaction.annotation.Transactionalin einer Federanwendung konsequent zu verwenden.

Andernfalls kann es zu diesem Fehler kommen.

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

........

Caused by: java.sql.SQLException: Protocol violation: [0]

1
Hinweis: Diese Antwort ist ein Sonderfall meiner Antwort
Jidehem

3

Deklarativer Transaktionsumfang

Sowohl mit der Spring- als auch mit der JPA- @TransactionAnnotation können Sie den Umfang einer bestimmten Anwendungstransaktion definieren.

Wenn eine Servicemethode mit der @TransactionalAnnotation kommentiert wird , wird sie in einem Transaktionskontext ausgeführt. Wenn die Servicemethode mehrere DAO oder Repositorys verwendet, werden alle Lese- und Schreibvorgänge in derselben Datenbanktransaktion ausgeführt.

Frühling @Transactional

Die org.springframework.transaction.annotation.TransactionalAnmerkung ist seit der Version 1.2 des Spring-Frameworks (ca. 2005) verfügbar und ermöglicht es Ihnen, die folgenden Transaktionseigenschaften festzulegen:

  • isolation: die zugrunde liegende Datenbankisolationsstufe
  • noRollbackForund noRollbackForClassName: die Liste der Java- ExceptionKlassen, die ausgelöst werden können, ohne ein Transaktions-Rollback auszulösen
  • rollbackForund rollbackForClassName: die Liste der Java- ExceptionKlassen, die beim Auslösen einen Transaktions-Rollback auslösen
  • propagation: Der von der PropagationAufzählung angegebene Transaktionsausbreitungstyp . Zum Beispiel, wenn der Transaktionskontext vererbt werden kann (z. B. REQUIRED) oder ein neuer Transaktionskontext erstellt werden soll (z. B. REQUIRES_NEW) oder wenn eine Ausnahme ausgelöst werden soll, wenn kein Transaktionskontext vorhanden ist (z. B. MANDATORY) oder wenn eine Ausnahme ausgelöst werden soll wenn ein aktueller Transaktionskontext gefunden wird (z NOT_SUPPORTED. B. ).
  • readOnly: ob die aktuelle Transaktion nur Daten lesen soll, ohne Änderungen vorzunehmen.
  • timeout: Wie viele Sekunden sollte der Transaktionskontext ausgeführt werden dürfen, bis eine Timeout-Ausnahme ausgelöst wird.
  • valueoder transactionManager: der Name der Spring TransactionManagerBean, die beim Binden des Transaktionskontexts verwendet werden soll.

Java EE @Transactional

Die javax.transaction.TransactionalAnmerkung wurde durch die Java EE 7-Spezifikation hinzugefügt (circa 2013). Daher wurde die Java EE-Annotation 8 Jahre später als das Spring-Gegenstück hinzugefügt.

Das Java EE @Transactionaldefiniert nur 3 Attribute:

  • dontRollbackOn: Die Liste der Java- ExceptionKlassen, die ausgelöst werden können, ohne dass ein Transaktions-Rollback ausgelöst wird
  • rollbackOn: Die Liste der Java- ExceptionKlassen, die beim Auslösen einen Transaktions-Rollback auslösen
  • value: die von der TxTypeEnum vorgegebene Ausbreitungsstrategie . Zum Beispiel, wenn der Transaktionskontext vererbt werden kann (z. B. REQUIRED) oder ein neuer Transaktionskontext erstellt werden soll (z. B. REQUIRES_NEW) oder wenn eine Ausnahme ausgelöst werden soll, wenn kein Transaktionskontext vorhanden ist (z. B. MANDATORY) oder wenn eine Ausnahme ausgelöst werden soll wenn ein aktueller Transaktionskontext gefunden wird (z NOT_SUPPORTED. B. ).

Welches soll ich wählen?

Wenn Sie Spring oder Spring Boot verwenden, verwenden Sie die Spring- @TransactionalAnnotation, da Sie damit mehr Attribute als die Java EE- @TransactionalAnnotation konfigurieren können .

Wenn Sie nur Java EE verwenden und Ihre Anwendung auf einem Java EE-Anwendungsserver bereitstellen, verwenden Sie die Annotation Java EE `` @ Transactional`.

Weitere Informationen dazu, wie sich die Konfiguration der Isolationsstufe bei Verwendung der Spring- oder Java EE- @TransactionalDefinitionen unterscheidet, finden Sie in diesem Artikel .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.