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


153

Non capisco qual è la differenza effettiva tra le annotazioni javax.transaction.Transactionale org.springframework.transaction.annotation.Transactional?

È org.springframework.transaction.annotation.Transactionalun'estensione javax.transaction.Transactionalo hanno un significato totalmente diverso? Quando dovrebbero essere usati ciascuno di essi? Primavera @Transactinalnel livello di servizio e javax in DAO?

Grazie per aver risposto.

Risposte:


125

Spring ha definito la propria annotazione transazionale per rendere transazionali i metodi del bean Spring, anni fa.

Java EE 7 ha finalmente fatto la stessa cosa e ora consente ai metodi bean CDI di essere transazionali, oltre ai metodi EJB. Quindi da Java EE 7, definisce anche la propria annotazione Transazionale (ovviamente non può riutilizzare quella di Primavera).

In un'applicazione Java EE 7, utilizzerai l'annotazione Java EE.

In un'applicazione Spring, utilizzerai l'annotazione Spring.

Il loro uso è lo stesso: informare il contenitore (Java EE o Spring) che un metodo è transazionale.


28
Oltre a ciò: per governare l'universo, Spring ha anche aggiunto il supporto implicito, javax.transaction.Transactionalquindi ora è possibile utilizzarlo anche nelle applicazioni Spring senza ulteriori azioni. IMO, questa è stata una decisione piuttosto sbagliata dal punto di vista del design , perché per mia esperienza molti sviluppatori confondono inconsciamente questi due nel loro codice, il che porta a problemi in seguito.
Yuriy Nakonechnyy,

16
Inoltre, org.springframework.transaction.annotation.Transactionaloffre più opzioni (come readOnly, timeout) dijavax.transaction.Transactional
pierrefevrier

1
@yura, quali problemi hai riscontrato?
Lee Chee Kiam,

1
@LeeCheeKiam, per favore vedi due risposte qui sotto
Yuriy Nakonechnyy,

50

Un'altra differenza è come Spring gestisce le annotazioni @Transactional

  • org.springframework.transaction.annotation.Transactional è sempre preso in considerazione
  • javax.transaction.Transactional viene preso in considerazione solo quando sono presenti transazioni EJB3. La presenza delle transazioni EJB3 viene verificata se la classe javax.ejb.TransactionAttributeè disponibile nel percorso di classe (dalla versione 2.5.3 alla 3.2.5). Quindi puoi finire con le tue annotazioni che non vengono prese in considerazione se solo javax.transaction.Transactionalnel tuo percorso di classe e non javax.ejb.TransactionAttribute. Questo può essere il caso se stai lavorando con Hibernate: hibernate-core (4.3.7.Final) dipende da jboss-transaction-api_1.2_spec (1.0.0.Final), che non fornisce javax.ejb.TransactionAttribute.


non è sempre preso, se è su un metodo privato per esempio non sarà preso.
sciopero il

36

Si prega di fare attenzione (questo problema si è verificato in Tomcat),

Se l'applicazione è un'applicazione Web di PRIMAVERA e si sta utilizzando il meccanismo di gestione delle transazioni di Spring, ovvero @org.springframework.transaction.annotation.Transactionalnon mescolarlo con javax.transaction.Transactional.

Cioè Usa sempre, @org.springframework.transaction.annotation.Transactionalin un'applicazione a molla in modo coerente.

Altrimenti potremmo finire con questo errore,

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

........

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

1
Nota: questa risposta è un caso speciale della mia risposta
Jidehem,

3

Ambito di transazione dichiarativo

Sia l' @Transactionannotazione Spring che JPA consentono di definire l'ambito di una determinata transazione dell'applicazione.

Pertanto, se un metodo di servizio viene annotato con l' @Transactionalannotazione, verrà eseguito in un contesto transazionale. Se il metodo di servizio utilizza più DAO o repository, tutte le operazioni di lettura e scrittura degli annunci verranno eseguite nella stessa transazione del database.

Primavera @Transactional

L' org.springframework.transaction.annotation.Transactionalannotazione è disponibile dalla versione 1.2 del framework Spring (circa 2005) e consente di impostare le seguenti proprietà transazionali:

  • isolation: il livello di isolamento del database sottostante
  • noRollbackFore noRollbackForClassName: l'elenco delle Exceptionclassi Java che possono essere attivate senza innescare un rollback della transazione
  • rollbackFore rollbackForClassName: l'elenco delle Exceptionclassi Java che attivano un rollback della transazione quando viene lanciato
  • propagation: il tipo di propagazione della transazione fornito Propagationdall'Enum. Ad esempio, se il contesto della transazione può essere ereditato (ad es. REQUIRED) O creare un nuovo contesto di transazione (ad es. REQUIRES_NEW) O se deve essere generata un'eccezione se non è presente alcun contesto di transazione (ad es. MANDATORY) O se deve essere generata un'eccezione se viene trovato un contesto di transazione corrente (ad es NOT_SUPPORTED.).
  • readOnly: se la transazione corrente deve leggere solo i dati senza applicare alcuna modifica.
  • timeout: quanti secondi deve essere consentito l'esecuzione del contesto della transazione fino a quando non viene generata un'eccezione di timeout.
  • valueoppure transactionManager: il nome del TransactionManagerbean Spring da utilizzare per l'associazione del contesto della transazione.

Java EE @Transactional

L' javax.transaction.Transactionalannotazione è stata aggiunta dalla specifica Java EE 7 (circa 2013). Quindi, l'annotazione Java EE è stata aggiunta 8 anni dopo quella della sua controparte Spring.

Java EE @Transactionaldefinisce solo 3 attributi:

  • dontRollbackOn: l'elenco delle Exceptionclassi Java che possono essere attivate senza attivare un rollback della transazione
  • rollbackOn: l'elenco delle Exceptionclassi Java che attivano un rollback della transazione quando viene lanciato
  • value: la strategia di propagazione, proposta TxTypedall'Enum. Ad esempio, se il contesto della transazione può essere ereditato (ad es. REQUIRED) O creare un nuovo contesto di transazione (ad es. REQUIRES_NEW) O se deve essere generata un'eccezione se non è presente alcun contesto di transazione (ad es. MANDATORY) O se deve essere generata un'eccezione se viene trovato un contesto di transazione corrente (ad es NOT_SUPPORTED.).

Quale scegliere?

Se si utilizza Spring o Spring Boot, utilizzare l' @Transactionalannotazione Spring , in quanto consente di configurare più attributi rispetto @Transactionalall'annotazione Java EE .

Se si utilizza Java EE da solo e si distribuisce l'applicazione su un server delle applicazioni Java EE, utilizzare l'annotazione Java EE `` @ Transactional``.

Per ulteriori dettagli su come la configurazione del livello di isolamento differisce quando si utilizzano le @Transactionaldefinizioni EE Spring o Java , consultare questo articolo .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.