martedì 10 marzo 2015

Gestire la transazionalità con Spring

Vai all'indice

In questo post approfondirò un aspetto di cui finora ho solo accennato, ma che ha una grande importanza nelle applicazioni J2EE, ovvero la gestione della transazionalità con Spring.
Una transazione è una sequenza di azioni svolte in un database che vengono trattate come una singola unità di lavoro . Queste azioni dovrebbero o essere interamente completate o non prevedere alcun effetto nel caso qualcosa vada storto. La gestione delle transazioni è una parte importante di un RDBMS orientato alle applicazioni enterprise per assicurare l’integrità e la coerenza dei dati . Il concetto di transazionalità può essere definito dalle seguenti quattro proprietà descritte dall’acronimo inglese ACID:


  • Atomicity: Una transazione deve essere trattata come una singola unità di lavoro quindi se una sola operazione dell'intera sequenza di operazioni della transazione non avrà esito positivo, allora tutta la transazione non andrà a buon fine. 
  • Consistency: Rappresenta la consistenza dell'integrità referenziale del database, chiavi primarie univoche nelle tabelle.
  • Isolation: Ci possono essere molte transazioni che elaborano gli stessi dati nello stesso momento, ogni transazione dove essere isolata dalle altre per prevenire la corruzione dei dati.
  • Durability: Una volta che una transazione è stata completata, i risultati di tale operazione devono essere resi permanenti e non possono essere cancellati dal database a causa di una anomalia.

Un database RDBMS deve garantire tutte le quattro proprietà per ogni transazione . Da un punto di vista pratico al termine di una transazione dovrà essere eseguita la commit per consolidare le operazioni, in caso contrario sarà eseguito il rollback su tutte le operazioni.
Il framework Spring fornisce un livello astratto al di sopra delle sottostanti API per la gestione delle transazioni.
 

Transazioni locali e transazioni globali


Le transazioni locali sono specifiche di una singola risorsa come ad esempio una connessione JDBC, mentre le operazioni globali possono occupare più risorse transazionali come ad esempio una transazione in un sistema distribuito .
La gestione delle transazioni locali può essere utile in un ambiente informatico centralizzato in cui le risorse delle applicazioni si trovano in un unico sito, e la gestione delle transazioni comporta solo un gestore di dati locali in esecuzione su una singola macchina.
La gestione globale delle transazioni è necessaria dove risorse sono distribuite su più sistemi. In tal caso, la gestione delle transazioni deve essere fatto sia a livello locale e globale. Pertanto una transazione globale distribuita viene eseguita su più sistemi, e la sua esecuzione richiede un coordinamento tra il sistema di gestione delle transazioni globali e tutti i gestori locali di dati di tutti i sistemi coinvolti.

Transaction management programmatica o dichiarativa.


Spring supporta due tipi di transaction management.
  1. Transaction management programmatica: significa gestire la transazione tramite la programmazione. Questo dà una estrema flessibilità, ma è difficile da mantenere.
  2. Transaction management dichiarativa: è l’approccio preferibile in quanto separa il transaction management dal codice. Questa metodologia è più semplice da gestire poiché con qualche configurazione XML e l’uso delle annotazioni si applica una funzionalità comune in tutto il codice.
Per utilizzare la gestione delle transazioni tramite le annotazioni è sufficiente aggiungere 3 bean nel file di configurazione xml :

  • <context:annotation-config/>: indica al framework Spring di collegare le annotazioni con le classi e con i metodi.
  • <tx:annotation-driven/>: Aggiunge automaticamente il supporto alle transazioni al fine includere il codice in ambito transazionale.
  • Inizializzare il bean DataSourceTransactionManager con i parametri di connessione.

Di seguito sono riportati i tag xml da inserire nel file di configurazione di Spring per abilitare l’annotazione @Transactional. 

<context:annotation-config/>
<!-- Questo tag abilita le annotations transactions -->
<tx:annotation-driven  transaction-manager="transactionManager"/>
<bean id="transactionManager"
  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName" value="org.apache.derby.jdbc.ClientDriver"></property>
  <property name="url" value="jdbc:derby://localhost:1527/derby/derbyDB"></property>
  <property name="username" value="test"></property>
  <property name="password" value="test"></property>
</bean>


Uso dell’annotazione @Transactional
L’annotazione @Transactional a livello di classe include tutti i metodi di quella classe nell’ambito transazionale. L’annotazione @Transactional possiede proprietà come: readOnly, isolation, propagation, rollbackFor, noRollbackFor, utilizzate per controllare la transazione o comunicare con altre transazioni in corso. La proprietà readonly=true è utilizzata per indicare che un metodo verrà utilizzato esclusivamente per eseguire query di selezione, mentre impostando readonly=false potremo eseguire anche operazioni come: update, insert e delete. Di default readonly è impostato a false. Altra proprietà interessante è rollbackFor e noRollbackFor.Di default Spring esegue il RollBack di una transazione per le eccezioni di tipo RuntimeException o di eccezioni non controllate.
Altre proprietà interessanti sono Isolation, che indica la misura in cui una transazione è isolata dal lavoro di altre transazioni, e Propagation che specifica il comportamento nel caso in cui un metodo transazionale viene eseguito quando esiste già un contesto di transazione.


Conclusioni
La transazionalità è un tema molto importante e grazie a Spring è possibile gestirla con un alto livello di astrazione. Questo post dà una panoramica generale su questo tema, tuttavia gli aspetti da approfondire sono molteplici. La documentazione dettagliata è disponibile qui.

Hai apprezzato questo post? Conferma le mie competenze o scrivi una segnalazione sul mio profilo Linkedin!

Nessun commento:

Posta un commento