Transakcje
Transkrypt
Transakcje
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 2 // początek transakcji agent.bookPassage(card, price){ em.persist(reservation); 3 4 5 pp.byCredit(customer, card, price); } // rollback // koniec transakcji ... ... // 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 ... // początek transakcji agent.listAvailableCabins(2); 3 4 agent.listAvailableCabins(2); // koniec transakcji // commit ... ... 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 ... agent.setCabin(99); // początek transakcji ... // początek transakcji agent.listAvailableCabins(2); 3 4 agent.listAvailableCabins(2); // koniec transakcji // commit ... 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