Transakcje 1. Model ACID. 2. Deklaratywne zarządzanie transakcjami, atrybuty transakcji. 3. Propagacja transakcji. transakcje rozproszone, propagacja kontekstu utrwalania. 3. Izolacja typowe problemy, blokady, poziomy izolacji, współbieżność optymistyczna. 1
Transakcje ACID Typowe transakcje s ą ACID ( atomic, consistent, isolated, durable): atomowe zbiór operacji wykonanych w całości lub wcale, spójne logika biznesowa zapewnia integralność składowanych danych, zmienianych podczas wykonywania transakcji. izolowane brak ingerencji ze strony innych procesów na wykonanie i przebieg transakcji, trwałe dane nie mog ą zostać utracone w przypadku awarii systemu. 2
Transakcje ACID public TicketDO bookpassage(creditcarddo card, double price) throws IncompleteConversationalState { if (customer == null cruise == null cabin == null) { throw new IncompleteConversationalState( ); try { Reservation reservation = new Reservation( customer, cruise, cabin, price); entitymanager.persist(reservation); this.processpayment.bycredit(customer, card, price); TicketDO ticket = new TicketDO(customer,cruise,cabin,price); return ticket; catch(exception e) { throw new EJBException(e); 3
Deklaratywne zarządzanie transakcjami Specyfikacja EJB umożliwia deklaratywne zarządzanie transakcjami. Zarządzanie (niejawne) transakcjami poprzez kontener EJB odbywa si ę na podstawie atrybutów transakcji. S ą one kontrolowane poprzez adnotacje @TransactionAttribute lub deskryptor wdrożenia. Dzięki temu zachowanie transakcji jest niezależne od logiki biznesowej. Deklaratywne zarządzanie transakcjami redukuje złożoność transakcji oraz upraszcza tworzenie rozbudowanych aplikacji biznesowych. 4
Atrybuty transakcji Atrybuty transakcji mog ą być zdefiniowane dla całego komponentu EJB lub dla poszczególnych jego metod. Drugi sposób, choć trudniejszy, zapewnia większ ą elastyczność. Specyfikacja określa następujące wartości dla atrybutów transakcji: NotSupported, Supports, Required (domyślnie), RequiresNew, Mandatory, Never. 5
Atrybuty transakcji import javax.ejb.stateless; import javax.ejb.transactionattribute; @Stateless @TransactionAttribute(NOT_SUPPORTED) public class TravelAgentBean implements TravelAgentRemote { public void setcustomer(customer cust) { @TransactionAtribute(REQUIRED) public TicketDO bookpassage(creditcarddo card, double price) { 6
Atrybuty transakcji <ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" version=3.0> <assembly-descriptor> <container-transaction> <method> <ejb-name>travelagentejb</ejb-name> <method-name> * </method-name> </method> <trans-attribute>notsupported</trans-attribute> </container-transaction> <container-transaction> <method> <ejb-name>travelagentejb</ejb-name> <method-name>bookpassage</method-name> </method> <trans-attribute>required</trans-attribute> </container-transaction> </assembly-descriptor> </ejb-jar> 7
Atrybut NotSupported klient EJB EJB kontekst transakcyjny klienta kontekst nietransakcyjny Wywołanie metody zawiesza transakcj ę do czasu powrotu. Zakres transakcji nie jest propagowany do komponentu EJB 8
Atrybut Supports klient EJB EJB klient EJB EJB kontekst transakcyjny klienta kontekst nietransakcyjny Atrybut Supports powoduje, że zakres transakcji (lub jego brak) jest propagowany do komponentu EJB. 9
Atrybut Required klient EJB EJB klient EJB EJB kontekst transakcyjny klienta kontekst transakcyjny EJB kontekst nietransakcyjny Wywołana metoda zostaje dołączona do kontekstu transakcyjnego klienta. W przypadku jego braku, metoda rozpoczyna własn ą transakcj ę w ramach której zostanie wykonana. 10
Atrybut RequiresNew klient EJB EJB klient EJB EJB kontekst transakcyjny klienta kontekst transakcyjny EJB kontekst nietransakcyjny Niezależnie od kontekstu klienta, tworzona jest nowa transakcja w ramach której zostanie wykonana wywoływana metoda. 11
Atrybut Mandatory klient EJB EJB klient EJB EJB kontekst transakcyjny klienta kontekst nietransakcyjny wyjątek EJBTransactionRequiredException Metoda musi być wykonana w ramach transakcji klienta. Jeśli wywołanie metody nie nastąpiło z wnętrza transakcji, zostaje zwrócony wyjątek. 12
Atrybut Never klient EJB EJB klient EJB EJB kontekst transakcyjny klienta kontekst nietransakcyjny wyjątek EJBException lub RemoteException Metoda nie może być wywołana wewnątrz zakresu transakcji. 13
Atrybuty zalecania i ograniczenia Odwołanie do menedżerów encji wymaga istnienia zakresu transakcji. Z tego powodu zaleca si ę używania w tych sytuacjach jednego z atrybutów: Required, RequiresNew, Mandatory. Metody komponentów sterowanych komunikatami mog ą deklarować jedynie atrybuty Required i NotSupported. Pozostałe atrybuty odnosz ą si ę do transakcji zainicjowanych przez klienta, wiec nie maj ą sensu w kontekście MDB poniewa ż te komponenty nie s ą w żaden bezpośredni sposób powiązane z klientem. Atrybut Mandatory nie może być używany z metodami stanowiącymi punkty końcowe (usługa WebServices). 14
Propagacja transakcji Komponenty biorące udział w transakcji rejestruj ą si ę w menadżerze transakcji. Po wykonaniu wszystkich zada ń przez komponenty, menadżer decyduje, czy transakcja zostanie potwierdzona ( commit), czy anulowana (rollback). Serwer EJB potrafi współpracować z innymi systemami transakcyjnymi w celu realizacji tzw. transakcji rozproszonych. Transakcje rozproszone wymagaj ą tzw. dwufazowego zatwierdzania. Najpopularniejszym stosowanym tutaj mechanizmem jest algorytm 2PC. 15
Protokół 2PC Protokół 2PC (ang. two-phase commit protocol) rozpoczyna działanie w momencie rozpoczęcia zatwierdzania transakcji rozproszonej i składa si ę z dwóch etapów. W pierwszym przygotowanie ( ang. prepare), każdy z uczestników transakcji przygotowuje si ę do jej lokalnego zatwierdzenia. Gdy wszyscy wyrazili gotowość zatwierdzenia rozpoczyna si ę druga faza zatwierdzenie (ang. commit). Jeśli jakakolwiek z lokalnych transakcji nie mogła być zatwierdzona, wszystkie s ą odwoływane. Cały proces dwufazowego zatwierdzania jest koordynowany przez menadżera transakcji. 16
Propagacja kontekstu utrwalania Gdy menadżer encji o zakresie ograniczonym przez transakcj ę: jest wywoływany poza zakresem transakcji, kontekst utrwalania jest tworzony na czas wywołania metody, jest wywoływany wewnątrz transakcji, tworzony jest nowy kontekst pod warunkiem, ze nie istnieje ju ż kontekst powiązany z t ą transakcj ą. W takiej sytuacji zostanie użyty istniejący kontekst, wywołuje stanowy komponent sesyjny z rozszerzonym kontekstem utrwalania, zgłaszany jest błąd. 17
Izolacja brudne odczyty public List listavailablecabins(int bedcount) throws IncompleteConversationalState { if (cruise == null) throw new IncompleteConversationalState( ); Query query = entitymanager.createquery("select name " + "FROM Cabin c WHERE c.ship = :ship AND c.bedcount = :beds " + "AND NOT ANY (SELECT cabin from Reservation res " + "WHERE res.cruise = :cruise"); query.setparameter("ship", cruise.getship( )); query.setparameter("beds", bedcount); query.setparameter("cruise", cruise); return query.getresultlist( ); 18
Izolacja brudne odczyty travelagent.setcabinid(99); 1 // początek transakcji agent.bookpassage(card, price){ 2 4 5 em.persist(reservation); pp.bycredit(customer, card, price); // rollback // koniec transakcji 3 // początek transakcji obj.listavailablecabins(2); // commit // koniec transakcji: Brudne odczyty (dirty reads) występuj ą gdy jedna transakcja odczytuje dane zmieniane przez drug ą transakcj ę przed jej zatwierdzeniem. 19
Izolacja powtarzalne odczyty 1 2 4 // początek transakcji agent.listavailablecabins(2); agent.listavailablecabins(2); // koniec transakcji // commit 3 cabin c = em.find(cabin.class, 99); // początek transakcji c.setbedcount(3); // koniec transakcji: // commit Powtarzalne odczyty (repeatable reads) pojawiaj ą si ę jeśli żądamy gwarancji, aby wielokrotne odczyty tych samych danych w ramach transakcji dawały takie same wyniki. 20
Izolacja odczyty fantomowe 1 2 4 // początek transakcji agent.listavailablecabins(2); agent.listavailablecabins(2); // koniec transakcji // commit 3 agent.setcabin(99); // początek transakcji agent.bookpassage(card, price){ em.persist(reservation); // koniec transakcji: // commit Odczyty fantomowe (phantom reads) występuj ą gdy nowy rekord dodany do bazy jest rejestrowany przez transakcj ę, która rozpoczęła si ę przed jego dodaniem. 21
Blokady Aby umożliwić realizacj ę izolowanych transakcji bazy danych wykorzystuj ą blokady. Podstawowe typy blokad: odczytu blokuje możliwość zmiany danych odczytanych przez transakcj ę do czasu jej zakończenia. Transakcja nie modyfikuje danych (chroni przed powtarzalnymi odczytami), zapisu blokuje możliwość zmiany danych do czasu zakończenia transakcji, ale umożliwia ich odczyt (brudne odczyty), wyłączna do zapisu blokuje innym transakcjom możliwość zapisu i odczytu danych do czasu zakończenia transakcji, obrazy (snapshots) innym transakcjom udostępniana jest kopia danych z momentu przed rozpoczęciem transakcji. 22
Poziomy izolacji Poziom izolacji określa odporność transakcji na oddziaływanie z innymi, wykonywanymi równolegle operacjami na bazie danych. Dostępne poziomy izolacji w technologii JEE s ą określone w specyfikacji JDBC: read uncommited inne transakcje mog ą odczytywać niezatwierdzone dane, read commited - inne transakcje nie mog ą odczytywać niezatwierdzonych danych, repeatable read - inne transakcje nie mog ą ani odczytywać ani zmieniać niezatwierdzonych danych poniewa ż rekordy s ą blokowane podczas operacji odczytu. serializable transakcja ma wyłączny dostęp do danych, na których operuje poniewa ż następuje blokada tabel. 23
Poziomy izolacji Poziomy izolacji dla zasobów s ą ustawiane i zarządzane z poziomu kontenera EJB. Dokumentacja kontenera zawiera informacje czy i jak można je modyfikować. Transakcje zarządzane przez komponenty sesyjne lub sterowane komunikatami mog ą także być zarządzane poprzez API JDBC: InitialContext jndi = new InitialContext( ); DataSource source = (javax.sql.datasource) jndi.lookup( "java:comp/env/jdbc/titandb"); Connection con = source.getconnection( ); con.settransactionisolation( Connection.TRANSACTION_SERIALIZABLE); Należy pamiętać, że stosowanie restrykcyjnych poziomów izolacji zwykle wpływa niekorzystnie na wydajność aplikacji. 24
Współbieżność optymistyczna Założ enie: transakcje dotycz ą dużej liczby obiektów ale stosunkowo rzadko transakcje odwołuj ą si ę do tych samych obiektów. Rozwią zanie: schemat zarządzania wersjami. @Entity public class CruiseCabin { private int id; private Cabin cabin; private Cruise cruise; private boolean isreserved; private long version; @Version protected long getversion( ) { return version; 25
Współbieżność optymistyczna public TicketDO bookpassage(creditcarddo card, double price) throws IncompleteConversationalState { if (customer == null cruise == null cabin == null) { throw new IncompleteConversationalState( ); try { Query query = entitymanager.createquery( "SELECT cc FROM CruiseCabin cc WHERE" + "cc.cabin = :cabin AND cc.cruise = :cruise"); query.setparameter("cabin", cabin); query.setparameter("cruise", cruise); CruiseCabin cc = (CruiseCabin)query.getSingleResult(); if (cc.getisreserved( )) throw new EJBException("Kabina zarezerwowana"); cc.setisreserved(true); catch(exception e) { throw new EJBException(e); UPDATE CRUISE_CABIN SET isreserved=true, version=version + 1 WHERE id = 132 AND version = 101; 26
Zabezpieczenia programowe Interfejs EntityManager posiada metod ę lock() służąc ą do blokowania danych: package javax.persistence; public enum LockModeType{ READ, WRITE public interface EntityManager { void lock(object entity, LockModeType type); READ eliminuje odczyty brudne i powtarzalne. WRITE dodatkowo zwię ksza atrybut @Version. 27
Podsumowanie Transakcje s ą niezbędne aby zapewnić efektywnie i współbieżne operacje na zgromadzonych danych. Zarządzanie transakcjami odbywa sie automatycznie (kontener EJB) na podstawie deklaracji. Jawne zarządzanie jest możliwe (JTA) ale niezalecane. Spójność przetwarzanych danych może być zapewniona poprzez właściwy dobór poziomów izolacji oraz blokad. 28