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ź.

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.


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.


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]

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 .

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.