Transakcje w Dżakarcie - Jakarta Transactions

W Transakcje Dżakarta ( JTA ; dawniej transakcja Java API), jeden z Dżakarty EE API , umożliwia transakcji rozproszonych być wykonywane na wielu X / Open XA zasobów w Java środowiska. JTA to specyfikacja opracowana w ramach Java Community Process jako JSR 907. JTA zapewnia:

  • wytyczenie granic transakcji
  • X/Open XA API umożliwiające zasobom udział w transakcjach.

Architektura X/Open XA

W architekturze X/Open XA menedżer transakcji lub monitor przetwarzania transakcji (monitor TP) koordynuje transakcje w wielu zasobach, takich jak bazy danych i kolejki komunikatów. Każdy zasób ma własnego menedżera zasobów. Menedżer zasobów zazwyczaj ma własny interfejs API do manipulowania zasobem, na przykład interfejs API JDBC do pracy z relacyjnymi bazami danych. Ponadto menedżer zasobów umożliwia monitorowi TP koordynację rozproszonej transakcji między własnymi i innymi menedżerami zasobów. Wreszcie istnieje aplikacja, która komunikuje się z monitorem TP w celu rozpoczęcia, zatwierdzenia lub wycofania transakcji. Aplikacja komunikuje się również z poszczególnymi zasobami za pomocą własnego API do modyfikacji zasobu.

Implementacja JTA architektury X/Open XA

API JTA składa się z klas w dwóch pakietach Java :

JTA jest wzorowana na architekturze X/Open XA, ale definiuje dwa różne interfejsy API do wyznaczania granic transakcji. Rozróżnia serwer aplikacji, taki jak serwer EJB , i komponent aplikacji. Udostępnia interfejs, javax.transaction.TransactionManagerktóry jest używany przez sam serwer aplikacji do rozpoczynania, zatwierdzania i wycofywania transakcji. Udostępnia inny interfejs, javax.transaction.UserTransaction, który jest używany przez ogólny kod klienta, taki jak serwlet lub EJB, do zarządzania transakcjami.

Architektura JTA wymaga, aby każdy menedżer zasobów zaimplementował javax.transaction.xa.XAResourceinterfejs, aby mógł być zarządzany przez monitor TP. Jak wspomniano wcześniej, każdy zasób będzie miał swój własny interfejs API, na przykład:

Interfejs aplikacji do programowania

Jakarta Transactions API składa się z trzech elementów: interfejsu demarkacji transakcji aplikacji wysokiego poziomu, interfejsu menedżera transakcji wysokiego poziomu przeznaczonego dla serwera aplikacji oraz standardowego mapowania Java protokołu X/Open XA przeznaczonego dla menedżera zasobów transakcyjnych.

Interfejs UserTransaction

javax.transaction.UserTransactionInterfejs zapewnia aplikacja możliwość kontrolowania granic transakcji programowo. Ten interfejs może być używany przez programy klienckie Java lub komponenty EJB.

UserTransaction.begin()Metoda rozpoczyna transakcję globalnego i kojarzy transakcji z wątku wywołującego. Powiązanie transakcji z wątkiem jest zarządzane w przejrzysty sposób przez Menedżera Transakcji.

Obsługa zagnieżdżonych transakcji nie jest wymagana. Metoda UserTransaction.begin zgłasza NotSupportedException, gdy wątek wywołujący jest już skojarzony z transakcją, a implementacja Menedżera transakcji nie obsługuje transakcji zagnieżdżonych.

Propagację kontekstu transakcji między programami użytkowymi zapewniają leżące u ich podstaw implementacje menedżera transakcji na komputerach klienckich i serwerowych. Format kontekstu transakcji używany do propagacji jest zależny od protokołu i musi być negocjowany między hostami klienta i serwera. Na przykład, jeśli menedżer transakcji jest implementacją specyfikacji JTS , użyje formatu propagacji kontekstu transakcji określonego w specyfikacji CORBA OTS 1.1. Propagacja transakcji jest transparentna dla programów użytkowych.

@Adnotacja transakcyjna

javax.transaction.TransactionalAdnotacja zapewnia aplikacja możliwość kontrolowania granic transakcji deklaratywnie. Ta adnotacja może być zastosowana do dowolnej klasy, którą specyfikacja Jakarta EE definiuje jako zarządzany komponent bean (w tym zarządzane ziarna CDI).

Poniższy przykładowy kod ilustruje użycie @Transactional w zarządzanym beanie CDI z zakresem żądania:

@RequestScoped
public class ExampleBean {

    @Transactional
    public void foo() { // A transaction is active here
        
        // Do work

    } // After the method returns transaction is committed or rolled back
}

Zachowanie transakcyjne można skonfigurować za pomocą atrybutu w adnotacji. Dostępne opcje ściśle odzwierciedlają te ze specyfikacji EJB .

@Adnotacja TransactionScoped

javax.transaction.TransactionScopedAdnotacja zapewnia aplikacja zdolność do stwierdzenia, że w zakresie, w trakcie którego życie fasola jest przywiązany do czasu, gdy dana transakcja jest aktywna.

Poniższy przykładowy kod ilustruje użycie @TransactionScoped w zarządzanym beanie CDI z zakresem żądania:

@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());
    }
}

Jeśli metoda foo() zostanie najpierw wywołana na zarządzanej instancji ExampleBean, a następnie metoda bar() , wydrukowana liczba będzie wynosić 0, a nie 1. Dzieje się tak, ponieważ każda metoda miała własną transakcję, a zatem własną instancję TxScopedBean . Numer 1, który został ustawiony podczas wywołania foo() , nie będzie więc widoczny podczas wywołania bar() .

Obsługa UserTransaction w serwerze EJB

Serwery EJB muszą obsługiwać interfejs UserTransaction używany przez komponenty EJB bean z wartością BEAN w javax.ejb.TransactionManagement adnotacji (jest to nazywane transakcjami zarządzanymi przez ziarna lub BMT). Interfejs UserTransaction jest udostępniany komponentom EJB za pośrednictwem interfejsu EJBContext przy użyciu metody getUserTransaction lub bezpośrednio przez wstrzyknięcie przy użyciu @Resourceadnotacji ogólnej . W związku z tym aplikacja EJB nie łączy się bezpośrednio z menedżerem transakcji w celu rozgraniczenia transakcji; zamiast tego komponent bean EJB opiera się na serwerze EJB, aby zapewnić obsługę wszystkich swoich prac transakcyjnych zgodnie z definicją w specyfikacji Jakarta Enterprise Beans Specification. (Podstawowa interakcja między serwerem EJB a TM jest niewidoczna dla aplikacji; ciężar implementacji zarządzania transakcjami spoczywa na kontenerze EJB i dostawcy serwera).

Poniższy przykładowy kod ilustruje użycie UserTransaction za pośrednictwem transakcji zarządzanych przez ziarna w ziarnach sesji EJB:

@Stateless
@TransactionManagement(BEAN)
public class ExampleBean {

    @Resource
    private UserTransaction utx;

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

        // Do work

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

Alternatywnie UserTransaction można uzyskać z 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();
    }
}

Zauważ jednak, że w powyższym przykładzie, jeśli @TransactionManagement(BEAN)adnotacja zostanie pominięta, transakcja JTA jest automatycznie uruchamiana przy każdym foo()wywołaniu i jest automatycznie zatwierdzana lub wycofywana po foo()zakończeniu. Korzystanie z UserTransaction nie jest zatem konieczne w programowaniu EJB, ale może być potrzebne w przypadku bardzo wyspecjalizowanego kodu.

Obsługa UserTransaction w JNDI

UserTransaction powinien być dostępny pod java:comp/UserTransaction(jeśli implementacja JTA jest zainstalowana w środowisku).

Zobacz też

Bibliografia

Zewnętrzne linki