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