Java Transaction API

Da Wikipedia, l'enciclopedia libera.
Vai alla navigazione Vai alla ricerca

La Java Transaction API (JTA) è una delle API offerte dalla Java EE (Java Enterprise Edition), ed ha lo scopo di abilitare delle transazioni distribuite, eseguite attraverso risorse X/Open XA multiple in un ambiente Java. JTA è una specifica sviluppata sotto le direttive del Java Community Process come JSR 907. La JTA mette a disposizione:

  • una demarcazione dei confini delle transazioni.
  • delle X/Open XA API che permettono alle risorse di partecipare alle transazioni.

Architettura X/Open XA[modifica | modifica wikitesto]

In questa architettura, un Transaction Manager o un Transaction Processing monitor (TP monitor) coordina le transazioni attraverso le risorse multiple come database o code di messaggi. Ogni risorsa ha il suo Resource Manager. Il Resource Manager, tipicamente, utilizza le proprie API per manipolare le risorse, ad esempio far lavorare le API JDBC con i database relazionali. Il Resource Manager permette, inoltre, che un TP monitor coordini una transazione distribuita tra se stesso e altri Resource Manager. Finalmente, entra in azione l'applicazione che comunica con il TP monitor per eseguire le tipiche operazioni sulle transazioni, come l'avvio (begin), il commit e il rollback. L'applicazione comunica anche con le risorse individuali per modificarle, usando le proprie API.

Implementazione della JTA nell'architettura X/Open XA[modifica | modifica wikitesto]

La JTA API consiste in una serie di classi suddivise nei due seguenti package Java:

La JTA è fabbricata sul modello dell'architettura X/Open XA, ma definisce due differenti API per il demarcamento dei confini delle transazioni. Si distingue tra un application server come un server EJB e un application component. Fornisce un'interfaccia javax.transaction.TransactionManager, che è usato dall'application server vero e proprio per fare dei begin, dei commit e dei rollback delle transazioni. Fornisce inoltre un'interfaccia differente, la javax.transaction.UserTransaction, che è usata dal codice generico di un client, come una servlet o un EJB, per gestire le transazioni.

L'architettura JTA richiede che ogni Resource Manager implementi l'interfaccia javax.transaction.xa.XAResource in modo da essere gestita dal TP monitor. Come spiegato in precedenza, ogni risorsa avrà la propria API specifica, per esempio:

  • I database relazionali usano JDBC
  • I servizi di messaggistica usano JMS
  • Le risorse EIS (Enterprise Information System) generalizzate usano la Java EE Connector Architecture.

Java Transaction API[modifica | modifica wikitesto]

La Java Transaction API consiste di tre elementi: un'interfaccia di demarcamento delle transazioni ad alto livello nell'applicazione, un'interfaccia Transaction Manager sempre ad alto livello, e una mappatura Java standard del protocollo X/Open XA destinato ad un Resource Manager transazionale.

Interfaccia UserTransaction[modifica | modifica wikitesto]

L'interfaccia javax.transaction.UserTransaction fornisce all'applicazione l'abilità di controllare i limiti delle transazioni in modo programmatico. Questa interfaccia può essere usata dai programmi Java lato client o dai bean EJB.

Il metodo begin() inizia una transazione globale e la associa con il thread in chiamata. L'associazione transaction-to-thread è gestita in modo trasparente dal Transaction Manager.

Non è richiesto un supporto per le transazioni annidate. Il metodo begin() lancia l'eccezione NotSupportedException quando il thread è già associato con una transazione e l'implementazione del Transaction Manager non supporta le transazioni annidate.

Il contesto in cui si propaga la transazione tra applicazioni è assegnato dalle implementazioni in background dei Transaction Manager sulle macchine client e server. Il formato del contesto usato per la propagazione è dipendente dal protocollo e deve essere negoziato tra gli host client e server. Per esempio, se il Transaction Manager è un'implementazione della specifica JTS, userà quello specificato in CORBA OTS 1.1. La propagazione delle transazioni è trasparente all'applicazione.

Annotazione @Transactional[modifica | modifica wikitesto]

L'annotazione javax.transaction.Transactional fornisce all'applicazione l'abilità di controllare i limiti delle transazioni in modo dichiarativo. Questa annotazione può essere applicata ad ogni classe che la Java EE definisce come managed bean (che include i CDI managed bean).

L'esempio di codice sottostante illustra l'uso di @Transactional in un ambito dove si richiedono i CDI managed bean:

@RequestScoped
public class ExampleBean {

    @Transactional
    public void foo() { // La transazione qui è attiva
        
        // Esegue del codice

    } // Dopo il return, alla transazione viene fatto un commit o un rollback
}

Il comportamento della transazione può essere configurato con un attributo nell'annotazione.

Annotazione @TransactionScoped[modifica | modifica wikitesto]

L'annotazione javax.transaction.TransactionScoped fornisce all'applicazione la possibilità di dichiarare che, l'ambito durante il quale un Bean vive, è legato al tempo in cui una certa transazione è attiva.

L'esempio di codice sottostante mostra l'uso di @TransactionScoped in un ambito dove si richiedono i CDI managed bean:

@TransactionScoped
public class TxScopedBean {
    public int number;

    public int getNumber() {return number;}
    public void setNumber(int number) {this.number = number;}
}

@RequestScoped
public class ExampleBean {

    @Inject
    private TxScopedBean txScopedBean;

    @Transactional
    public void foo() {
        txScopedBean.setNumber(1);
    }

    @Transactional
    public void bar() {
        System.out.print(tXscopedBean.getNumber());
    }
}

Se il metodo foo() è chiamato per primo su un'istanza gestita di ExampleBean e successivamente viene chiamato il metodo bar(), il numero stampato a video sarà 0 e non 1. Questo perché ogni metodo ha la propria transazione e perciò anche la propria istanza di TxScopedBean. Il numero 1 che viene assegnato durante la chiamato a foo() non sarà quindi visibile durante la chiamata a bar().

Supporto di UserTransaction nei server EJB[modifica | modifica wikitesto]

I server EJB sono richiesti per supportare l'interfaccia UserTransaction per l'uso dagli EJB Bean con il valore BEAN nell'annotazione javax.ejb.TransactionManagement (questa è chiamata bean-managed transaction o BMT). L'interfaccia UserTransaction è esposta ai componenti EJB attraverso sia con l'interfaccia EJBContext che usa il metodo getUserTransaction, sia direttamente usando la generica annotazione @Resource. Pertanto, un'applicazione EJB non si interfaccia direttamente con il Transaction Manager per la demarcazione delle transazioni; invece, gli EJB Bean contano sul server EJB per fornire supporto per tutto il suo lavoro transazionale, come definito nell'Enterprise JavaBeans Specification. (L'interazione sottostante tra EJB Server e TM è trasparente all'applicazione; l'onere di implementare la gestione delle transazioni è sul EJB container e sul server provider.)

Il codice di esempio sottostante mostra l'uso di UserTransaction attraverso le transazioni bean-managed in una session EJB Bean:

@Stateless
@TransactionManagement(BEAN)
public class ExampleBean {

    @Resource
    private UserTransaction utx;

    public void foo() {
        // start a transaction
        utx.begin();

        // Do work

        // Commit it
        utx.commit();
    }
}

In alternativa, la UserTransaction può essere ottenuta dal SessionContext:

@Stateless
@TransactionManagement(BEAN)
public class ExampleBean {

    @Resource
    private SessionContext ctx;

    public void foo() {
        UserTransaction utx = ctx.getUserTransaction();

        // start a transaction
        utx.begin();

        // Do work

        // Commit it
        utx.commit();
    }
}

Bisogna notare che nell'esempio se l'annotazione @TransactionManagement(BEAN) fosse stata omessa, una transazione JTA sarebbe iniziata automaticamente ogni volta che viene chiamato foo() e, sempre automaticamente, avverrebbe un commit e un rollback quando si esce da foo(). L'uso di una UserTransaction non è quindi necessario nella programmazione EJB, ma può essere richiesto nel codice più specializzato.

Supporto di UserTransaction in JNDI[modifica | modifica wikitesto]

UserTransaction è disponibile sotto java:comp/UserTransaction, se nell'ambiente è installata un'implementazione della JTA.

Implementazioni Open source per la JTA[modifica | modifica wikitesto]

Alcune implementazioni open source per la JTA sono elencate qui di seguito (aggiornato a settembre 2010):

  • Narayana
  • Atomikos TransactionsEssentials
  • Bitronix JTA

Voci correlate[modifica | modifica wikitesto]

Collegamenti esterni[modifica | modifica wikitesto]

  Portale Informatica: accedi alle voci di Wikipedia che trattano di informatica