Primavera - Gestione delle transazioni

Una transazione di database è una sequenza di azioni che vengono trattate come una singola unità di lavoro. Queste azioni dovrebbero essere completate completamente o non avere alcun effetto. La gestione delle transazioni è una parte importante dell'applicazione aziendale orientata a RDBMS per garantire l'integrità e la coerenza dei dati. Il concetto di transazione può essere descritto con le seguenti quattro proprietà chiave descritte comeACID -

  • Atomicity - Una transazione dovrebbe essere trattata come una singola unità di operazione, il che significa che l'intera sequenza di operazioni ha esito positivo o negativo.

  • Consistency - Questo rappresenta la coerenza dell'integrità referenziale del database, chiavi primarie univoche nelle tabelle, ecc.

  • Isolation- È possibile che vengano elaborate molte transazioni con lo stesso set di dati contemporaneamente. Ogni transazione dovrebbe essere isolata dalle altre per prevenire il danneggiamento dei dati.

  • Durability - Una volta completata una transazione, i risultati di questa transazione devono essere resi permanenti e non possono essere cancellati dal database a causa di un errore di sistema.

Un vero e proprio sistema di database RDBMS garantirà tutte e quattro le proprietà per ogni transazione. La visione semplicistica di una transazione emessa al database utilizzando SQL è la seguente:

  • Inizia la transazione utilizzando il comando di inizio transazione .

  • Esegui varie operazioni di eliminazione, aggiornamento o inserimento utilizzando query SQL.

  • Se tutte le operazioni hanno esito positivo, eseguire il commit altrimenti eseguire il rollback di tutte le operazioni.

Il framework Spring fornisce un livello astratto in cima a diverse API di gestione delle transazioni sottostanti. Il supporto per le transazioni di Spring mira a fornire un'alternativa alle transazioni EJB aggiungendo funzionalità di transazione ai POJO. Spring supporta la gestione delle transazioni sia programmatica che dichiarativa. Gli EJB richiedono un server delle applicazioni, ma la gestione delle transazioni Spring può essere implementata senza la necessità di un server delle applicazioni.

Transazioni locali e globali

Le transazioni locali sono specifiche per una singola risorsa transazionale come una connessione JDBC, mentre le transazioni globali possono estendersi su più risorse transazionali come la transazione in un sistema distribuito.

La gestione delle transazioni locali può essere utile in un ambiente informatico centralizzato in cui i componenti e le risorse dell'applicazione si trovano in un unico sito e la gestione delle transazioni coinvolge solo un gestore dati locale in esecuzione su una singola macchina. Le transazioni locali sono più facili da implementare.

La gestione delle transazioni globali è necessaria in un ambiente informatico distribuito in cui tutte le risorse sono distribuite su più sistemi. In tal caso, la gestione delle transazioni deve essere effettuata sia a livello locale che globale. Una transazione distribuita o globale viene eseguita su più sistemi e la sua esecuzione richiede il coordinamento tra il sistema di gestione delle transazioni globali e tutti i gestori di dati locali di tutti i sistemi coinvolti.

Programmatico vs dichiarativo

Spring supporta due tipi di gestione delle transazioni:

  • Gestione delle transazioni programmatiche - Ciò significa che devi gestire la transazione con l'aiuto della programmazione. Questo ti dà un'estrema flessibilità, ma è difficile da mantenere.

  • Gestione delle transazioni dichiarativa : significa separare la gestione delle transazioni dal codice aziendale. Utilizzi solo annotazioni o configurazioni basate su XML per gestire le transazioni.

La gestione delle transazioni dichiarativa è preferibile rispetto alla gestione delle transazioni a livello di codice, sebbene sia meno flessibile della gestione delle transazioni a livello di codice, che consente di controllare le transazioni tramite il codice. Ma come una sorta di preoccupazione trasversale, la gestione dichiarativa delle transazioni può essere modularizzata con l'approccio AOP. Spring supporta la gestione delle transazioni dichiarative tramite il framework Spring AOP.

Astrazioni delle transazioni primaverili

La chiave per l'astrazione della transazione Spring è definita dall'interfaccia org.springframework.transaction.PlatformTransactionManager , che è la seguente:

public interface PlatformTransactionManager {
   TransactionStatus getTransaction(TransactionDefinition definition);
   throws TransactionException;
   
   void commit(TransactionStatus status) throws TransactionException;
   void rollback(TransactionStatus status) throws TransactionException;
}

Suor n Metodo e descrizione
1

TransactionStatus getTransaction(TransactionDefinition definition)

Questo metodo restituisce una transazione attualmente attiva o ne crea una nuova, in base al comportamento di propagazione specificato.

2

void commit(TransactionStatus status)

Questo metodo esegue il commit della transazione data, in relazione al suo stato.

3

void rollback(TransactionStatus status)

Questo metodo esegue un rollback della transazione data.

Il TransactionDefinition è l'interfaccia nucleo del supporto delle transazioni in primavera ed è definita come segue -

public interface TransactionDefinition {
   int getPropagationBehavior();
   int getIsolationLevel();
   String getName();
   int getTimeout();
   boolean isReadOnly();
}

Suor n Metodo e descrizione
1

int getPropagationBehavior()

Questo metodo restituisce il comportamento di propagazione. Spring offre tutte le opzioni di propagazione delle transazioni familiari da EJB CMT.

2

int getIsolationLevel()

Questo metodo restituisce il grado in cui questa transazione è isolata dal lavoro di altre transazioni.

3

String getName()

Questo metodo restituisce il nome di questa transazione.

4

int getTimeout()

Questo metodo restituisce il tempo in secondi in cui la transazione deve essere completata.

5

boolean isReadOnly()

Questo metodo restituisce se la transazione è di sola lettura.

Di seguito sono riportati i possibili valori per il livello di isolamento:

Suor n Isolamento e descrizione
1

TransactionDefinition.ISOLATION_DEFAULT

Questo è il livello di isolamento predefinito.

2

TransactionDefinition.ISOLATION_READ_COMMITTED

Indica che le letture sporche sono impedite; possono verificarsi letture non ripetibili e letture fantasma.

3

TransactionDefinition.ISOLATION_READ_UNCOMMITTED

Indica che possono verificarsi letture sporche, letture non ripetibili e letture fantasma.

4

TransactionDefinition.ISOLATION_REPEATABLE_READ

Indica che le letture sporche e non ripetibili sono impedite; possono verificarsi letture fantasma.

5

TransactionDefinition.ISOLATION_SERIALIZABLE

Indica che le letture sporche, non ripetibili e fantasma sono impedite.

Di seguito sono riportati i possibili valori per i tipi di propagazione:

Sr.No. Propagazione e descrizione
1

TransactionDefinition.PROPAGATION_MANDATORY

Supporta una transazione in corso; genera un'eccezione se non esiste alcuna transazione corrente.

2

TransactionDefinition.PROPAGATION_NESTED

Viene eseguito all'interno di una transazione nidificata se esiste una transazione corrente.

3

TransactionDefinition.PROPAGATION_NEVER

Non supporta una transazione in corso; genera un'eccezione se esiste una transazione corrente.

4

TransactionDefinition.PROPAGATION_NOT_SUPPORTED

Non supporta una transazione in corso; piuttosto eseguire sempre in modo non transazionale.

5

TransactionDefinition.PROPAGATION_REQUIRED

Supporta una transazione in corso; ne crea uno nuovo se non esiste.

6

TransactionDefinition.PROPAGATION_REQUIRES_NEW

Crea una nuova transazione, sospendendo la transazione corrente, se esistente.

7

TransactionDefinition.PROPAGATION_SUPPORTS

Supporta una transazione in corso; viene eseguito in modo non transazionale se non esiste.

8

TransactionDefinition.TIMEOUT_DEFAULT

Utilizza il timeout predefinito del sistema di transazione sottostante o nessuno se i timeout non sono supportati.

L' interfaccia TransactionStatus fornisce un modo semplice per il codice transazionale di controllare l'esecuzione della transazione e interrogare lo stato della transazione.

public interface TransactionStatus extends SavepointManager {
   boolean isNewTransaction();
   boolean hasSavepoint();
   void setRollbackOnly();
   boolean isRollbackOnly();
   boolean isCompleted();
}

Sr.No. Metodo e descrizione
1

boolean hasSavepoint()

Questo metodo restituisce se questa transazione contiene internamente un savepoint, cioè, è stata creata come transazione annidata basata su un savepoint.

2

boolean isCompleted()

Questo metodo restituisce se questa transazione è stata completata, ovvero se è già stato eseguito il commit o il rollback.

3

boolean isNewTransaction()

Questo metodo restituisce true nel caso in cui la transazione corrente sia nuova.

4

boolean isRollbackOnly()

Questo metodo restituisce se la transazione è stata contrassegnata come solo rollback.

5

void setRollbackOnly()

Questo metodo imposta la transazione come solo rollback.