lunedì 23 luglio 2012

Gestione delle transazioni: vs EJB3 Spring


Gestione delle transazioni è un tema che è generalmente lasciata alla tenera cura di uno sviluppatore senior (o architetto). Visti i messaggi provenienti da alcuni attori della comunità JavaEE che con versioni più recenti di JavaEE non hai bisogno di Spring più, ero interessato a qualche fatto controllo sulle modalità di gestione delle transazioni è stata gestita in entrambe le tecnologie. Nota: questi messaggi sono stati inviati già un anno e mezzo fa e mi ha spinto a scrivere questo articolo .

Transaction demarcazione

Si noti che sebbene entrambe le tecnologie forniscono una demarcazione programmatica transazione (quindi avviare la transazione commit / rollback), ci concentreremo sulla demarcazione dichiarativa in quanto sono più facili da usare nella vita reale. In EJB3, le transazioni sono delimitati da l'annotazione @ TransactionAttribute. L'annotazione può essere impostata sulla classe, nel qual caso ogni metodo avrà l'attributo transazionale, o un metodo per. Annotazione a livello di metodo può ignorare l'annotazione a livello di classe. Annotazioni sono trovati automaticamente dal JavaEE-compliant application server. In primavera, l'annotazione prima è sostituito dal proprietario annotazione @ transazionale. Il comportamento è esattamente lo stesso (annotazione di metodo / livello di classe e la possibilità di override). Le annotazioni possono essere trovato solo quando il bean file di primavera definizione contiene lo spazio dei nomi http://www.springframework.org/schema/tx così come il seguente frammento:

1.tx: annotation-driven />
In alternativa, entrambe le tecnologie forniscono un modo ortogonale per impostare la demarcazione della transazione: in EJB3, si può usare l'EJB JAR descrittore di deployment (ejb-jar.xml), mentre in primavera, tutti i file di configurazione di primavera farà.

Operazioni di propagazione

In EJB3, ci sono esattamente 6 valori possibili di propagazione: obbligatori, richiesti (default), REQUIRES_NEW, Supporti, NOT_SUPPORTED e MAI. Primavera aggiunge il supporto per NESTED (vedi sotto).

Le transazioni nidificate

Transazioni nidificate sono operazioni che vengono avviati successivamente impegnati / annullate da una rollback durante l'esecuzione della transazione root. Risultati transazione nidificata sono limitati al campo di applicazione di tale operazione solo (non ha alcun effetto sulla transazione ombrello). Transazioni nidificate non sono ammessi in EJB3, sono in primavera.

Transazione di sola lettura

Di sola lettura le transazioni sono usate meglio con alcune banche dati o quadri ORM come Hibernate. In quest'ultimo caso, Hibernate ottimizza le sessioni in modo che non hanno mai flush ( cioè non inserire mai i cambiamenti dalla cache al database sottostante). Non ho trovato un modo (ancora) per qualificare un transazione come di sola lettura in EJB3 (aiuto benvenuto). In primavera, @ Transactional ha un parametro readOnly per implementare le operazioni di sola lettura:

1.@ Transactional (readOnly = true )

Metodo di chiamate locali

In chiamate a metodi locali, il metodo di un bean A () chiama un altro metodo B () sulla stessa istanza. Il comportamento atteso che deve essere attributi di transazione di metodo (B) viene presa in considerazione. Non è il caso né tecnologie, ma entrambi offrono una soluzione alternativa. In EJB3, è necessario iniettare un'istanza della stessa classe e chiamare il metodo su questa istanza al fine di utilizzare gli attributi di transazione. Ad esempio:

01.@ Stateless
02.pubblico MyServiceBean implementa MyServiceLocal {
03. 
04.@ EJB
05.private di servizio MyServiceLocal;
06. 
07.@ TransactionAttribute (TransactionAttributeType.NOT_SUPPORTED)
08.pubblica vuoto A () {
09. 
. 10service.B ();
11.}
12. 
13.@ TransactionAttribute (TransactionAttributeType.REQUIRES_NEW)
14.pubblica vuoto B () {
15. 
16....
17.}
18.}
In primavera, per impostazione predefinita, la gestione delle transazioni viene gestita attraverso la pura proxy Java. Se si desidera avere la gestione delle transazioni in chiamate a metodi locali, dovrete accendere AspectJ. Questo è fatto facilmente nella definizione primavera file di chicchi (ma attenzione gli effetti collaterali, consultare la documentazione di primavera per maggiori dettagli):

1.tx: annotation-driven mode "aspectj" />

Gestione delle eccezioni e rollback

La gestione delle eccezioni è l'area con le maggiori differenze tra la primavera e EJB3. In EJB3, solo le eccezioni di runtime gettato da un rollback un metodo delimitato transazione intorno a questo metodo di default. Al fine di imitare questo comportamento per eccezioni controllate, si deve annotare la classe di eccezione con @ ApplicationException (rollback = true). Allo stesso modo, se si desidera eliminare questo comportamento per le eccezioni runtime, annota la classe eccezione con @ ApplicationException (rollback = false). Questo ha lo svantaggio di non poter utilizzare la stessa classe eccezione rollback in un metodo e ad impegnare ancora nonostante l'eccezione di un altro metodo. Al fine di raggiungere questo obiettivo, è necessario gestire la transazione di programmazione:

01.@ Stateless
02.pubblico MyServiceBean implementa MyServiceLocal {
03. 
04.@ Resource
05.private contesto SessionContext;
06. 
07.pubblica vuoto A () {
08. 
09.provare {
10. 
11....
12. 
13.cattura (MyException e) {
14. 
15.context.setRollbackOnly ();
16.}
17.}
18.}
In primavera, le eccezioni di runtime anche causare rollback delle transazioni. Per modificare questo comportamento, utilizzare gli attributi rollbackFor o noRollbackFor di @ Transactional:

01.pubblica MyServiceImpl {
02. 
03.@ Resource
. 04private contesto SessionContext;
05. 
06.@ Transactional (rollbackFor = MyException. class )
07.pubblica vuoto A () {
08. 
09....
10.}
11.}

Conclusione

Non si può negare che JavaEE ha fatto passi da gigante nella giusta direzione con la sua versione 6.Eppure, i piccoli dettagli tenere avermi verso primavera.