Transakcje w Dżakarcie

Jakarta Transactions ( JTA ; dawniej Java Transaction API), jeden z interfejsów API Jakarta EE , umożliwia przeprowadzanie transakcji rozproszonych w wielu zasobach X/Open XA w środowisku Java . JTA była specyfikacją opracowaną w ramach Java Community Process jako JSR 907. JTA zapewnia:

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 zwykle ma własny interfejs API do manipulowania zasobem, na przykład interfejs JDBC do pracy z relacyjnymi bazami danych. Ponadto zarządca zasobów umożliwia monitorowi TP koordynację transakcji rozproszonych pomiędzy jego własnym i innych zarządców zasobów. Wreszcie jest aplikacja, która komunikuje się z monitorem TP, aby rozpocząć, zatwierdzić lub cofnąć transakcje. Aplikacja komunikuje się również z poszczególnymi zasobami za pomocą własnego API w celu modyfikacji zasobu.

Implementacja JTA architektury X/Open XA

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

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

Architektura JTA wymaga, aby każdy menedżer zasobów zaimplementował interfejs javax.transaction.xa.XAResource , 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 rozgraniczenia 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

Interfejs javax.transaction.UserTransaction zapewnia aplikacji możliwość programowego kontrolowania granic transakcji. Ten interfejs może być używany przez programy klienckie Java lub komponenty bean EJB.

Metoda UserTransaction.begin() uruchamia transakcję globalną i wiąże ją z wątkiem wywołującym. Powiązanie transakcji z wątkiem jest zarządzane w przejrzysty sposób przez Menedżera transakcji.

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

Propagacja kontekstu transakcji między aplikacjami jest zapewniana przez podstawowe implementacje menedżera transakcji na komputerach klienckich i serwerach. Format kontekstu transakcji używany do propagacji zależy 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 niewidoczna dla aplikacji.

@Adnotacja transakcyjna

Adnotacja javax.transaction.Transactional umożliwia aplikacji deklaratywne kontrolowanie granic transakcji. Ta adnotacja może być zastosowana do dowolnej klasy, którą specyfikacja Jakarta EE definiuje jako zarządzany komponent bean (w tym komponent bean zarządzany przez CDI).

Poniższy przykładowy kod ilustruje użycie @Transactional w zarządzanym komponencie bean CDI o zakresie żądań:


   

    
        
        
        

     
 @RequestScoped  public  class  ExampleBean  {  @Transactional  public  void  foo  ()  {  // Transakcja jest tutaj aktywna  // Wykonaj pracę  }  // Po zwróceniu metody transakcja zostaje zatwierdzona lub wycofana  } 

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

Adnotacja @TransactionScoped

Adnotacja javax.transaction.TransactionScoped zapewnia aplikacji możliwość zadeklarowania, że ​​zakres, w którym żyje komponent bean, jest powiązany z czasem aktywności danej transakcji.

Poniższy przykładowy kod ilustruje użycie @TransactionScoped w zarządzanym komponencie bean CDI o zakresie żądań:


   
      

        
          



   

    
      @TransactionScoped  klasa  publiczna  TxScopedBean  {  publiczny  numer  int  ;  public  int  getNumber  ()  {  zwraca  numer  ;}  public  void  setNumber  (  int  number  )  {  this  .  liczba  =  liczba  ;}  }  @RequestScoped  klasa  publiczna  ExampleBean  {  @Inject  private  TxScopedBean  

    
       
        
    

    
       
        
    
 txScopedBean  ;  @Transactional  public  void  foo  ()  {  txScopedBean  .  ustawLiczbę  (  1  );  }  @Transactional  public  void  bar  ()  {  System  .  na  zewnątrz  print  (  tXscopedBean  .  getNumber  ());  }  } 

Jeśli metoda foo() zostanie najpierw wywołana na zarządzanej instancji ExampleBean, a następnie wywołana zostanie metoda bar(), wydrukowana liczba będzie równa 0, a nie 1. Wynika to z faktu, że każda metoda miała własną transakcję, a zatem własną instancję TxScopedBean . Liczba 1, która została ustawiona podczas wywołania foo() nie będzie zatem widoczna podczas wywołania bar() .

Obsługa UserTransaction w serwerze EJB

EJB muszą obsługiwać interfejs UserTransaction do użytku przez komponenty bean EJB z wartością komponentu BEAN w adnotacji javax.ejb.TransactionManagement (nazywa się to transakcjami zarządzanymi przez komponent bean lub BMT). Interfejs UserTransaction jest udostępniany komponentom EJB albo przez interfejs EJBContext przy użyciu metody getUserTransaction, albo bezpośrednio przez wstrzyknięcie przy użyciu ogólnego @Resource adnotacja. 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 polega na serwerze EJB, który zapewnia obsługę wszystkich operacji transakcyjnych zgodnie z definicją w specyfikacji Jakarta Enterprise Beans. (Podstawowa interakcja między serwerem EJB a TM jest niewidoczna dla aplikacji; ciężar wdrożenia zarządzania transakcjami spoczywa na kontenerze EJB i dostawcy serwera).

Poniższy przykładowy kod ilustruje użycie UserTransaction poprzez transakcje zarządzane przez komponent bean w komponencie sesyjnym EJB:



   

    
      

       
        
        

        

        
        
    
 @Stateless  @TransactionManagement  (  BEAN  )  klasa  publiczna  ExampleBean  {  @Resource  private  UserTransaction  utx  ;  public  void  foo  ()  {  // rozpocznij transakcję  utx  .  rozpocząć  ();  // Wykonaj pracę  // Zatwierdź  utx  .  zatwierdzić  ();  }  } 

Alternatywnie, UserTransaction można uzyskać z SessionContext:



   

    
      

       
           

        
        

        

        
        
    
 @Stateless  @TransactionManagement  (  BEAN  )  klasa  publiczna  ExampleBean  {  @Resource  private  SessionContext  ctx  ;  public  void  foo  ()  {  UserTransaction  utx  =  ctx  .  getUserTransaction  ();  // rozpocznij transakcję  utx  .  rozpocząć  ();  // Wykonaj pracę  // Zatwierdź  utx  .  zatwierdzić  ();  }  } 

Należy jednak zauważyć, że w powyższym przykładzie, jeśli adnotacja @TransactionManagement(BEAN) zostanie pominięta, transakcja JTA jest automatycznie uruchamiana za każdym razem, gdy wywoływana jest funkcja foo() i jest automatycznie zatwierdzana lub wycofywana, gdy funkcja foo() zostaje zakończona. Korzystanie z UserTransaction nie jest zatem konieczne w programowaniu EJB, ale może być potrzebne w przypadku bardzo specjalistycznego 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ż

Linki zewnętrzne