Zarządzanie transakcjami
Wprowadzenie do systemów baz danych
Transakcja
Transakcjami nazywamy procedury, które wprowadzają zmiany
do bazy danych lub które wyszukują dane
Transakcją może być jedna instrukcja lub zbiór instrukcji
tworzących pewną logiczną jednostkę pracy
O transakcjach mówimy w kontekście współużytkowania danych
przez wielu użytkowników i powstawania ewentualnych
wzajemnych konfliktów
Samo czytanie danych (bez ich modyfikacji) nie powoduje
konfliktów
Przyczyną powstawania konfliktów są modyfikacje danych w
środowisku wielu użytkowników
System zarządzania bazą danych powinien rozwiązać
potencjalne konflikty powstające przy przetwarzaniu transakcji
Wymagania stawiane transakcjom
Niepodzielność – albo wszystkie modyfikacje wchodzące w
skład transakcji są wykonane albo żadna
Spójność – wszystkie transakcje muszą zachować spójność i
integralność bazy danych
Izolacja – jeśli transakcja modyfikuje dane, to te dane mogą być
czasowo niespójne, dlatego muszą być niedostępne dla innych
transakcji dopóty, dopóki transakcja nie skończy ich używać
Trwałość – gdy transakcja się kończy, to wszystkie zmiany
przez nią dokonane muszą zostać w pełni utrwalone – nawet w
przypadku awarii sprzętu
(ang. ACID – Atomicity, Consistency, Isolation, Durability)
Właściwości transakcji
Transakcja to jedna modyfikacja lub seria modyfikacji bazy
danych traktowana tak jakby była to jedna modyfikacja
Jeśli modyfikacje zachodzą, to wszystkie zachodzą w jednej
chwili
Użytkownicy mogą zobaczyć stan bazy danych przed transakcją
lub po jej zakończeniu, ale nigdy w trakcie
Przykłady transakcji i zagrożeń
Rezerwacja miejsca w samolocie – możliwe dwukrotne
sprzedanie tego samego miejsca
Zwiększanie pensji 300 pracowników – możliwa awaria sprzętu
w trakcie zapisu na dysk
Transfer pieniędzy z konta na konto – obie operacje muszą być
wykonana albo żadna
W trakcie transferu pieniędzy z konta na konto ktoś sprawdza
sumę wszystkich kont, i nie może widzieć stanu pośredniego (z
jednego konta pieniądze zniknęły, a na drugim się nie pojawiły)
Zatwierdzanie transakcji
W języku SQL do zatwierdzenia transakcji służy instrukcja COMMIT
Do odwołania transakcji służy polecenie ROLLBACK
W standardzie języka SQL nie ma instrukcji zaczynającej transakcję
SQL Server umożliwia przeprowadzanie transakcji w 3 trybach
AutoCommit – każde polecenie SQL stanowi odrębną transakcję
Explicit – transakcję trzeba rozpocząć poleceniem
BEGIN TRAN[SACTION] i zakończyć poleceniem COMMIT lub
ROLLBACK
Implicit – transakcja rozpoczyna się automatycznie po wykonaniu 1
polecenia SQL i trzeba ją zakończyć jawnie poleceniem COMMIT lub
ROLLBACK
PostgreSQL domyślnie pracuje w trybie automatycznego zatwierdzania
transakcji
Aby jawnie rozpocząć transakcję, należy wydać instrukcję BEGIN
Problem utraconej modyfikacji
Transakcja 1
Transakcja 2
BEGIN
Wartość pola
Miejsca
Miejsca = 10
Odczyt (Miejsca = 10)
BEGIN
Miejsca = 10
Miejsca = Miejsca + 1
Odczyt (Miejsca = 10)
Miejsca = 10
UPDATE Miejsca = 11
Miejsca = Miejsca + 5
Miejsca = 11
COMMIT
UPDATE Miejsca = 15
Miejsca = 15
COMMIT
Miejsca = 15
Problem niezatwierdzonej
zależności
Transakcja 1
Transakcja 2
Wartość pola
Miejsca
BEGIN
Miejsca = 10
Odczyt (Miejsca = 10)
Miejsca = 10
Miejsca = Miejsca + 1
Miejsca = 10
UPDATE Miejsca = 11
ROLLBACK
BEGIN
Miejsca = 11
Odczyt (Miejsca = 11)
Miejsca = 11
Miejsca = Miejsca + 5 = 16
Miejsca = 10
UPDATE Miejsca = 16
Miejsca = 16
COMMIT
Miejsca = 16
Częściowe rozwiązanie problemu
Zapisując nową wartość, w miejsce starej, należy sprawdzić czy
stara wartość nie została zmieniona od czasu ostatniego
odczytu (wartość ostatniego odczytu należy zapamiętać)
UPDATE SET Miejsca = nowa_wartość
WHERE Miejsca = poprzednio_odczytana_wartość AND …
Jeśli wartość Miejsca uległa zmianie od ostatniego odczytu, to
modyfikacja nie zostanie wykonana i otrzymamy komunikat o
aktualizacji 0 liczby wierszy
Jeśli wartość Miejsca nie uległa zmianie od ostatniego odczytu,
to modyfikacja zostanie wykonana i otrzymamy komunikat o
aktualizacji 1 wiersza
Izolacja transakcji – język SQL
W języku SQL określono 4 poziomy izolacji transakcji
W celu zdefiniowania poziomów izolacji transakcji określono 3
rodzaje nieprawidłowych odczytów
Poziom izolacji transakcji określa dozwolone dla danego
poziomu nieprawidłowe odczyty
Im wyższy poziom izolacji, tym mniej dopuszczalnych
nieprawidłowych odczytów
Im wyższy poziom izolacji tym wolniejsza praca systemu
zarządzania bazą danych
Dopuszczenie nieprawidłowych odczytów przyspiesza pracę
systemu zarządzania bazą danych w porównaniu z najwyższym
poziomem izolacji - szeregowym
Nieprawidłowe odczyty
Brudny odczyt (Dirty read): pierwsza transakcja modyfikuje
wiersz, a druga go czyta, zanim zmiana została zatwierdzona
przez instrukcję COMMIT. Jeśli pierwsza transakcja została
anulowana, zmiana nie miała miejsca i druga transakcja
przeczytała wiersz, który naprawdę nigdy nie istniał
Odczyt bez powtórzeń (Non-repeatable read): pierwsza
transakcja czyta wiersz. Druga go usuwa lub modyfikuje i
wykonuje COMMIT przed pierwszą. Teraz pierwsza transakcja
mogłaby przeczytać ten sam wiersz jeszcze raz i otrzymać inne
wyniki
Nieprawidłowe odczyty
Odczyt widmo (Phantom): pierwsza transakcja odczytuje
wiersze spełniające predykat. Druga wstawia wartości
(instrukcja INSERT) lub je modyfikuje (instrukcja UPDATE) tak,
że one również spełniają predykat. Następne wykonanie tego
samego zapytania przez pierwszą transakcję da inne wyniki
Poziomy izolacji i dozwolone
odczyty
Poziom izolacji
Brudny
odczyt
Odczyt bez
powtórzeń
Odczyt
widmo
READ UNCOMMITED
TAK
TAK
TAK
READ COMMITED
NIE
TAK
TAK
REPEATABLE READ
NIE
NIE
TAK
SERIALIZABLE
NIE
NIE
NIE
Określanie poziomu izolacji
SET TRANSACTION ISOLATION LEVEL
{READ UNCOMMITED | READ COMMITED | REPEATABLE
READ | SERIALIZABLE}
READ WRITE | READ ONLY
PostgreSQL obsługuje tylko poziomy: READ COMMITED
(domyślny) i SERIALIZABLE
wybranie innego poziomu izolacji powoduje ustawienie
odpowiedniego wyższego poziomu
Szeregowy harmonogram
transakcji
Transakcje są wykonywane kolejno bez przeplatania się
operacji między transakcjami
Każda transakcja musi się zakończyć zanim zacznie się nowa
transakcja
Szeregowy harmonogram transakcji gwarantuje, że baza
danych nigdy nie znajdzie się w stanie niespójnym
Nieszeregowy harmonogram transakcji
W środowisku wielu użytkowników wiele transakcji może nie
komunikować się ze sobą i być wykonywane równolegle
Szeregowalność to określenie takich harmonogramów
nieszeregowych, które zachowują się jak szeregowe
Harmonogram nieszeregowy jest poprawny, jeśli tworzy taki
sam wynik jak pewne wykonanie szeregowe
W celu zapewnienia szeregowalności wiele systemów stosuje
blokady
Przykład
Linie lotnicze sprzedają bilety na 100 lotów dziennie,
samolotami o średniej liczbie miejsc w samolocie 120
Daje to średnio 12000 biletów dziennie, 500 biletów na
godzinę, 8 biletów na minutę
Szeregowanie wszystkich transakcji jest niemożliwe z uwagi
na czas trwania jednej transakcji, szczególnie, gdy klient
długo się zastanawia
Szeregowanie wszystkich transakcji jest także zbyteczne,
gdyż transakcje sprzedaży biletów na poszczególne loty są
wzajemnie niezależnie
Szeregowanie transakcji sprzedaży biletów na pojedynczy
lot jest w pełni wykonalne – szczególnie, gdy uwzględnimy,
że bilety na jeden lot są sprzedawane przez kilka dni
Blokady
Wiele baz danych implementuje izolację transakcji za pomocą
blokad, które ograniczają dostęp do danych, używanych przez
transakcję, innym transakcjom
Istnieją dwa typy blokad
Blokada współdzielona (shared lock), która pozwala innym
użytkownikom odczytywać dane, ale nie pozwala na ich
aktualizację
Blokada wyłączna, która nie zezwala innym transakcjom
nawet na czytanie danych
Zakleszczenie
BEGIN
BEGIN
UPDATE wiersz 64
(blokada wiersza 64)
UPDATE wiersz 68
(blokada wiersza 68)
UPDATE wiersz 68
(czekanie na odblokowanie wiersza 68)
UPDATE wiersz 64
(czekanie na odblokowanie wiersza 64)
Auto-ROLLBACK
COMMIT
Przebieg wykonywania transakcji
Rozpoczęcie – wprowadzenie transakcji do menadżera
Rejestracja wstępnych informacji w dzienniku transakcji
Sprowadzenie rekordów bazy danych
Rejestracja obrazu danych przed transakcją
Obliczenie nowych wartości
Rejestracja obrazu danych po transakcji
Rejestracja zatwierdzenia
Zapis nowych rekordów do bazy danych
Po przerwaniu działania w dowolnym momencie można odtworzyć
stan bazy danych przed lub po transakcji
Transakcje rozproszone
W rozproszonych bazach danych dane są rozmieszczone na
różnych serwerach – tzw. serwerach sprzężonych
Komercyjne serwery baz danych obsługują transakcje
rozproszone, czyli transakcje obejmujące modyfikacje danych
ulokowanych na różnych serwerach
MS SQL Server wyposażony jest w usługę MS DTS (Distributed
Transaction Coordinator) do kontroli transakcji rozproszonych i
gwarantuje spójność wszystkich transakcji na SQL Serverze i
serwerach z nim sprzężonych
Warunkiem poprawnego wykonania transakcji rozproszonej jest
jej zatwierdzenie na wszystkich serwerach