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

152

Nie rozumiem, jaka jest rzeczywista różnica między adnotacjami javax.transaction.Transactionala org.springframework.transaction.annotation.Transactional?

Czy org.springframework.transaction.annotation.Transactionaljest przedłużeniem, javax.transaction.Transactionalczy też mają zupełnie inne znaczenie? Kiedy należy użyć każdego z nich? Wiosna @Transactinalw warstwie serwisowej i javax w DAO?

Dzięki za odpowiedź.

stamis
źródło

Odpowiedzi:

125

Wiosna zdefiniowała swoją własną adnotację transakcyjną, aby metody Spring bean były transakcyjne, lata temu.

Java EE 7 w końcu zrobiła to samo i pozwala teraz, oprócz metod EJB, na transakcyjne metody CDI bean. Tak więc od Java EE 7 definiuje również własną adnotację transakcyjną (oczywiście nie może ponownie użyć tej Spring).

W aplikacji Java EE 7 będziesz używać adnotacji Java EE.

W aplikacji Spring użyjesz adnotacji Spring.

Ich zastosowanie jest takie samo: informowanie kontenera (Java EE lub Spring), że metoda jest transakcyjna.

JB Nizet
źródło
28
Co więcej: aby rządzić wszechświatem, Spring dodał również ukrytą obsługę, dzięki javax.transaction.Transactionalczemu można go było teraz używać również w aplikacjach Spring bez żadnych dodatkowych działań. IMO, była to dość zła decyzja z punktu widzenia projektowania , ponieważ z mojego doświadczenia wynika, że ​​wielu programistów nieświadomie myli te dwa elementy w swoim kodzie, co prowadzi do późniejszych problemów.
Yuriy Nakonechnyy
16
Ponadto org.springframework.transaction.annotation.Transactionaloferuje więcej opcji (takich jak readOnly, timeout) niżjavax.transaction.Transactional
pierrefevrier
1
@yura, jakie problemy zauważyłeś?
Lee Chee Kiam
1
@LeeCheeKiam proszę zobaczyć dwie odpowiedzi poniżej
Yuriy Nakonechnyy
50

Inną różnicą jest sposób, w jaki Spring obsługuje adnotacje @Transactional

  • Zawsze brana jest pod uwagę org.springframework.transaction.annotation.Transactional
  • javax.transaction.Transactional jest brane pod uwagę tylko wtedy, gdy obecne są transakcje EJB3. Obecność transakcji EJB3 odbywa się poprzez sprawdzenie, czy klasa javax.ejb.TransactionAttributejest dostępna w ścieżce klas (od wersji 2.5.3 do 3.2.5). W ten sposób możesz skończyć z nieuwzględnianiem adnotacji, jeśli tylko javax.transaction.Transactionalznajdują się one w Twojej ścieżce klas, a nie javax.ejb.TransactionAttribute. Może tak być, jeśli pracujesz z Hibernate: hibernate-core (4.3.7.Final) zależy od jboss-transaction-api_1.2_spec (1.0.0.Final), która nie zapewnia javax.ejb.TransactionAttribute.
Jidehem
źródło
9
Myślę, że nie stanowi to już problemu w Spring 4.2.0: javax.transaction.Transactional adnotation jest również obsługiwany jako bezpośredni zamiennik własnej adnotacji Springa
Arend v. Reinersdorff
nie zawsze jest pobierane, jeśli na przykład jest to metoda prywatna, nie zostanie pobrane.
strash
36

Proszę bądź ostrożny (ten problem wystąpił w Tomcat),

Jeśli Twoja aplikacja jest aplikacją internetową WIOSNA i używasz mechanizmu obsługi transakcji Springa @org.springframework.transaction.annotation.Transactional, to nie mieszaj go z javax.transaction.Transactional.

To jest Zawsze używaj, @org.springframework.transaction.annotation.Transactionalkonsekwentnie w aplikacji sprężynowej.

W przeciwnym razie możemy skończyć z tym błędem,

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
źródło
1
Uwaga: ta odpowiedź jest szczególnym przypadkiem mojej odpowiedzi
Jidehem
3

Deklaratywny zakres transakcji

@TransactionAdnotacja Spring i JPA pozwalają na zdefiniowanie zakresu transakcji danej aplikacji.

Tak więc, jeśli metoda usługi jest opatrzona @Transactionaladnotacją, będzie działać w kontekście transakcyjnym. Jeśli metoda usługi korzysta z wielu DAO lub repozytoriów, wszystkie operacje odczytu i zapisu reklam zostaną wykonane w tej samej transakcji bazy danych.

Wiosna @Transactional

org.springframework.transaction.annotation.TransactionalAdnotacji jest dostępna od wersji 1.2 ramach wiosennej (około 2005 roku), a to pozwala na ustawienie następujących właściwości transakcyjnych:

  • isolation: poziom izolacji bazowej bazy danych
  • noRollbackFororaz noRollbackForClassName: lista Exceptionklas Java , które można wyzwolić bez wyzwalania wycofania transakcji
  • rollbackFororaz rollbackForClassName: lista Exceptionklas Java , które wyzwalają wycofanie transakcji po wyrzuceniu
  • propagation: typ propagacji transakcji podany przez PropagationEnum. Na przykład, jeśli kontekst transakcji można odziedziczyć (np. REQUIRED) Lub należy utworzyć nowy kontekst transakcji (np. REQUIRES_NEW) Lub jeśli należy zgłosić wyjątek, jeśli nie ma kontekstu transakcji (np. MANDATORY) Lub jeśli należy zgłosić wyjątek jeśli zostanie znaleziony bieżący kontekst transakcji (np NOT_SUPPORTED.).
  • readOnly: czy bieżąca transakcja powinna tylko odczytywać dane bez wprowadzania zmian.
  • timeout: przez ile sekund kontekst transakcji powinien działać, zanim zostanie zgłoszony wyjątek limitu czasu.
  • valuelub transactionManager: nazwa TransactionManagerziarna Spring, która ma być używana podczas wiązania kontekstu transakcji.

Java EE @Transactional

javax.transaction.TransactionalAdnotacja dodano specyfikacją Java EE 7 (około 2013). Tak więc adnotacja Java EE została dodana 8 lat później niż jej odpowiednik Spring.

Java EE @Transactionaldefiniuje tylko 3 atrybuty:

  • dontRollbackOn: lista Exceptionklas Java , które można wyzwolić bez wyzwalania wycofania transakcji
  • rollbackOn: lista Exceptionklas Java , które powodują wycofanie transakcji podczas wyrzucania
  • value: strategia propagacji, podana przez TxTypeEnum. Na przykład, jeśli kontekst transakcji można odziedziczyć (np. REQUIRED) Lub należy utworzyć nowy kontekst transakcji (np. REQUIRES_NEW) Lub jeśli należy zgłosić wyjątek, jeśli nie ma kontekstu transakcji (np. MANDATORY) Lub jeśli należy zgłosić wyjątek jeśli zostanie znaleziony bieżący kontekst transakcji (np NOT_SUPPORTED.).

Który wybrać?

Jeśli używasz Spring lub Spring Boot, użyj @Transactionaladnotacji Spring , ponieważ pozwala ona skonfigurować więcej atrybutów niż @Transactionaladnotacja Java EE .

Jeśli używasz samego Java EE i wdrażasz swoją aplikację na serwerze aplikacji Java EE, użyj adnotacji Java EE `` @ Transactional`.

Więcej informacji na temat różnic w konfiguracji poziomu izolacji w przypadku korzystania z @Transactionaldefinicji Spring lub Java EE można znaleźć w tym artykule .

Vlad Mihalcea
źródło