Z+éo+-ona struktura transakcji II
Transkrypt
Z+éo+-ona struktura transakcji II
Ograniczenia płaskiej struktury transakcji Planowanie wyjazdu Poznań – Rockford k. Chicago BEGIN WORK S1: zarezerwuj lot z Poznania do Frankfurtu S2: zarezerwuj lot z Frankfurtu do Nowego Jorku (tego samego dnia) S3: zarezerwuj lot z Nowego Jorku do Chicago (tego samego dnia) S4: zarezerwuj przejazd autobusem z Chicago do Rockford S5: zarezerwuj hotel w Rockford ROLLBACK Problem: nie ma tego dnia wolnych miejsc w hotelu w Rockford k.Chicago, ale można tanio wynająć pokój w hotelu w Chicago Implementacja w klasycznym modelu transakcji: • Pojedyncza transakcja – wycofanie rezerwacji S4 pociągnie za sobą utratę rezerwacji S1, S2 i S3. • Zbiór logicznie powiązanych transakcji: nie można wycofać transakcji S1, S2 i S3. Klasyczny model transakcji nie odpowiada potrzebom aplikacji o złożonej strukturze przetwarzania Transakcje intensywnie przetwarzające dane Doliczenie odsetek – jedna duża transakcja DoliczOdsetki ( ) { exec sql BEGIN WORK; pobierz(procent); for (nr_konta = 1; nr_konta <= 100000; nr_konta++) ModyfikujKonto(nr_konta, odsetki); exec sql COMMIT WORK; return; } ModyfikujKonto(nr_konta long, odsetki float) { exec sql UPDATE konta SET saldo = saldo + (SELECT SUM(odsetki* ...) FROM operacje WHERE ...) WHERE id_konta = :nr_konta; ... return; }; • W przypadku awarii duża ilość utraconej pracy. • Niski stopień współbieżności. • Duże obciążenie dla systemu: duża ilość blokad oraz wielkość logu wycofania transakcji. Przykład II Doliczenie odsetek – zbiór autonomicznych transakcji DoliczOdsetki ( ) { pobierz(procent); for (nr_konta = 1; nr_konta <= 100000; nr_konta++) ModyfikujKonto(nr_konta, odsetki); return; } ModyfikujKonto(nr_konta long, odsetki float) { exec sql BEGIN WORK; exec sql UPDATE konta SET saldo = saldo + (SELECT SUM(odsetki* ...) FROM operacje WHERE ...) WHERE id_konta = :nr_konta; ... exec sql COMMIT WORK; return; }; • Wysoka współbieżność pracy systemu. • Niskie obciążenie systemu. • W przypadku awarii systemu – niespójność, utrata kontekstu pracy aplikacji. Rozszerzenia płaskiego modelu transakcji Zarządzanie przepływami pracy – System powinien wspomagać zarządzanie wyodrębnionymi fragmentami długich transakcji. Minimalizacja traconej pracy - System powinien umieć dzielić transakcje przetwarzające duże ilości danych na mniejsze odtwarzalne fragmenty w przypadku awarii procesu przetwarzania. Zwiększenie współbieżności przetwarzania – System powinien minimalizować blokowanie zasobów przez długo trwające transakcje. Zawieszanie procesu przetwarzania transakcji – System powinien umożliwiać zawieszanie procesu przetwarzania długo trwających transakcji i ich ponowne uruchamianie od momentu, w którym nastąpiło zawieszenie. Płaskie transakcje z punktami wycofania (ang. savepoints) Nowe operacje definiujące strukturę transakcji: SAVE WORK: savepoint ROLLBACK WORK (savepoint) BEGIN WORK ( SAVE WORK: 1) Operacja Operacja SAVE WORK: 2 Operacja Operacja SAVE WORK: 3 Operacja Operacja SAVE WORK: 5 Operacja Operacja Operacja SAVE WORK: 4 SAVE WORK: 6 Operacja Operacja Operacja SAVE WORK: 8 ROLLBACK WORK(2) Operacja Operacja SAVE WORK: 7 COMMIT WORK Operacja ROLLBACK WORK(5) Trwałe punkty wycofania Łańcuch transakcji Nowa operacja: CHAIN WORK = COMMIT WORK + BEGIN WORK Ti begin commit Ti+1 begin commit CHAIN WORK Ti: Atomowa operacja: { * COMMIT WORK Ti; * BEGIN WORK Ti+1; } ROLLBACK WORK Ti: Atomowa operacja: { * ROLLBACK WORK (Ti); * BEGIN WORK (Ti); } Restart systemu po awarii w trakcie transakcji Ti: Atomowa operacja: { * ROLLBACK WORK (Ti); * BEGIN WORK (Ti); } ROLLBACK WORK łańcuch transakcji: ??? Przenoszenie i odtwarzanie kontekstu transakcji DoliczOdsetki ( ) { pobierz(procent); for (nr_konta = 1; nr_konta <= 100000; nr_konta++) ModyfikujKonto(nr_konta, odsetki); return; } ModyfikujKonto(nr_konta long, odsetki float) { exec sql BEGIN WORK; exec sql UPDATE konta SET saldo = (1 + procent saldo) * saldo; WHERE id_konta = nr_konta; exec sql COMMIT WORK; return; }; SAGA Cel zwiększenie stopnia współbieżności transakcji 1. Zdefiniowanie łańcucha transakcji jako pojedynczej jed- nostki sterowania. 2. Saga jest jednostką atomowości, ale nie izolacji. 3. Atomowość całego łańcucha transakcji jest zapewniana w wyniku zastosowania transakcji kompensacyjnych. SAGA jest zbiorem płaskich transakcji s1, s2...,sn.. Transakcje te mogą być wykonywane sekwencyjnie lub współbieżnie. Każdej transakcji si (1 ≤ i ≤ n) odpowiada transakcja kompensacyjna csi, która wycofuje efekt działania transakcji si. Wynikiem poprawnego wykonania SAGI będzie sekwencja: s1,s2,...,si,...,sn-1,sn natomiast w przypadku wystąpienia błęu podczas wykonywania kroku j SAGI, wynikiem będzie sekwencja: s1,s2,...,sj(abort),csj-1,...,cs2,cs1. Transakcje zagnieżdżone Własności 1. Transakcje mają złożoną strukturę pozwalającą definiować związki między podzbiorami operacji w ramach pojedynczej transakcji. W ogólności jest to struktura hierarchiczna. 2. Korzeniem tej hierarchii jest transakcja główna (ang. top level transaction), a pozostałe węzły są pod-transakcjami. 3. Pod-transakcje danej transakcji mogą być współbieżne. BEGIN WORK BEGIN WORK BEGIN WORK . . call subtransaction . . . . call subtransaction . . . COMMIT WORK call subtransaction . call subtransaction . COMMIT WORK . COMMIT WORK BEGIN WORK . COMMIT WORK BEGIN WORK . COMMIT WORK Różne modele transakcji zagnieżdżonych: • otwarte • zamknięte • wielopoziomowe Typy pod-transakcji Czy pomyślne zakończenie transakcji powinno być uzależnione od sposobu zakończenia jej podtransakcji? Model transakcji zagnieżdżonych przewiduje dwóch podstawowych typów pod-transakcji: istnienie • transakcje krytyczne (ang. vital sub-transaction), których niepomyślne zakończenie powoduje wycofanie całej transakcji • transakcje niekrytyczne (ang. non vital sub-transaction), których niepomyślne zakończenie nie ma wpływu na sposób zakończenia całej transakcji Organizacja wczasów: BEGIN WORK T1 T11:organizacja podróży (vital) (vital) T12:rezerwacja hotelu T13:rezerwacja luksusowego samochodu (non vital) T14:rezerwacja dodatkowych atrakcji (non vital) COMMIT WORK Typy pod-transakcji Z pod-transakcjami krytycznymi mogą być powiązane transakcje warunkowe (ang. contingency), które są wykonywane jedynie w wypadku niepomyślnego zakończenia pod-transakcji krytycznych. Transakcje warunkowe służą do definiowania alternatywnych sposobów realizacji określonych zadań. BEGIN WORK T1 T111: rezerwacja samolotu when failed then T112: rezerwacja pociągu (contingency) ... Sposobem umożliwiającym zwalnianie zasobów systemowych przydzielonych zakończonym pod-transakcjom są transakcje kompensujące. Transakcje kompensujące muszą być zdefiniowane dla wszystkich pod-transakcji. Wykonują one działania przywracające stan bazy danych sprzed wykonania powiązanych z nimi pod-transakcji. BEGIN WORK T1 T11: rezerwacja samolotu; CT11: wycofanie rezerwacji samolotu; ... Zależności między pod-transakcjami W przeciwieństwie do transakcji głównej transakcje nie posiadają cechy trwałości D. pod- Reguła zatwierdzania - Zatwierdzenie pod-transakcji powoduje, że wprowadzone przez nią modyfikacje stają się dostępne (jedynie) dla transakcji rodzicielskiej. Podtransakcja zostaje ostatecznie zatwierdzona jedynie, jeżeli jest lokalnie zatwierdzona i wszystkie transakcje rodzicielskie aż do korzenia drzewa zostaną zatwierdzone. COMMIT Ti WHEN T committed COMMIT WORK; Reguła wycofywania - Jeżeli transakcja (pod-transakcja) jest wycofywana to jej wszystkie pod-transakcje potomne również zostaną wycofane, niezależnie od ich lokalnego stanu zatwierdzenia. Wycofywanie pod-transakcji jest rekurencyjnie stosowane do kolejnych niższych poziomów drzewa. Wycofywanie transakcji w korzeniu drzewa prowadzi do wycofania wszystkich podtransakcji składających się na transakcję zagnieżdżoną. Zamknięte i otwarte transakcje zagnieżdżone W zamkniętym modelu transakcji zagnieżdżonych transakcje główne posiadają wszystkie cechy ACID, a pod-transakcje cechy ACI. Reguła izolacji - Wszystkie modyfikacje wprowadzone przez pod-transakcje są widoczne dla transakcji rodzicielskich po lokalnym zatwierdzeniu pod-transakcji. Wszystkie obiekty utrzymywane przez transakcję rodzicielską są dostępne dla jej transakcji potomnych. Podtransakcje są w pełni izolowane od wszystkich innych pod-transakcji wewnątrz i na zewnątrz ich transakcji rodzicielskiej. Blokady pod-transakcji są dziedziczone przez transakcje rodzicielskie. W otwartym modelu transakcji zagnieżdżonych transakcja główna nie posiada cechy izolacji, cecha ta jest własnością pod-transakcji, które są liśćmi hierarchii transakcji. Umożliwia to zwiększenie stopnia współbieżności transakcji i zmniejszenie obciążenia systemów. Transakcje wielopoziomowe Transakcje wielopoziomowe są rozszerzeniem modelu transakcji zagnieżdżonych o wykorzystanie semantyki operacji. Kolejne poziomy zagnieżdżenia transakcji adresują warstwy semantyczne bazy danych. Każda warstwa jest zbiorem dobrze zdefiniowanych abstrakcyjnych typów danych. Najniższy poziom tworzy warstwa elementarnych i niepodzielnych operacji. Krotki: {wstaw, czytaj, modyfikuj, usuń} warstwa 2 Pliki: warstwa 1 {otwórz, zamknij, czytaj rekord, zapisz rekord} Strony: {czytaj, zapisz, modyfikuj nagłówek} warstwa 0 Implementacja operacji semantycznych Operacje semantyczne wykonywane w warstwie n są implementowane jako pod-transakcje wykonywane w warstwie n-1. zapisz_rekord(r) czytaj(p) modyfikuj_nagłówek(p) zapisz(p) Ze względu na topologię hierarchii transakcje wielopoziomowe są szczególnym przypadkiem modelu transakcji zagnieżdżonych, w którym hierarchie transakcji są zrównoważone i wszystkie mają taką samą wysokość. Własności transakcji wielopoziomowych Model transakcji wielopoziomowych pozwala na zwiększenie stopnia współbieżności transakcji zagnieżdżonych, przy zachowaniu cechy izolacji transakcji. Przykład: Dwa poziomy abstrakcji: • rekordy: operacje read(rekord) i write(rekord) • strony dyskowe: operacje fetch(page) i store(page) T1 r2(r4) f2(q) r1(r1) f2(p) f1(p) T2 w2(r3 ← 6) s2(p) f1(p) w1(r2 ← 3) s1(p) w2(r2 ← 4) f2(p) s2(p) Operacje na środkowym poziomie hierarchii nie są atomowe, jednak odpowiadające im podtransakcje są uszeregowalne. Dzięki temu, mimo braku pełnej uszeregowalności najniższego poziomu transakcji, historia transakcji T1 i T2 jest poprawna. stan przed: stan po: page: p: r1 = 1; r2 = 2; r3 = 3; page: p: r1 = 1; r2 = 4; r3 = 6; page: q: r4 = 0 page: q: r4 = 0 Przykład historii niepoprawnej T2 T1 r2(r4) f2(q) r1(r1) f2(p) f1(p) w2(r3 ← 6) w1(r2 ← 3) f1(p) s1(p) s2(p) w2(r2 ← 4) f2(p) s2(p) Transakcje implementujące operacje środkowego poziomu hierarchii nie są uszeregowalne: transakcje odpowiadające operacjom w2(r3) i w1(r2). stan przed: page: p: r1 = 1; r2 = 2; r3 = 3; page: q: r4 = 0 stan po: page: p: r1 = 1; r2 = 4; r3 = 3; page: q: r4 = 0 Synchronizacja ograniczona do najwyższego poziomu abstrakcji jest niewystarczająca. Powyższa historia jest niepoprawna, mimo że operacje semantyczne na poziomie środkowym są niekonfliktowe. Konflikty (z punktu widzenia komutatywnych operacji warstwy wyższej są to pseudo-konflikty) występują na najniższej warstwie, a zawierające je pod-transakcje są nieuszeregowalne. Niepoprawność powyższej historii transakcji wynika z braku atomowości operacji wyższych poziomów abstrakcji. Wielopoziomowa synchronizacja transakcji zagnieżdżonych Wielopoziomowa synchronizacja transakcji zagnieżdżonych polega na niezależnej synchronizacji transakcji (potransakcji) w oddzielnych warstwach. Każda warstwa obejmuje po dwa poziomy abstrakcji: • niższy widziany jako zbiór operacji; • wyższy widziany jako zbiór transakcji. T1 T2 warstwa I r2(r4) r1(r1) w2(r3←6) w1(r2←3) w2(r2←4) warstwa II f2(q) f2(p) f1(p) f1(p) s2(p) s1(p) f2(p) s2(p) Niezależność warstw pozwala na stosowanie w różnych warstwach różnych algorytmów synchronizacji. Uszeregowalność wielopoziomowa Wielopoziomowa historia transakcji jest parą: WHT = (F, <) gdzie: • F jest lasem drzew transakcji; • < jest relacją częściowego porządku zdefiniowana na zbiorze węzłów. Relacja < jest sumą relacji porządkujących węzły na poszczególnych poziomach drzew. Relacja <0 jest relacją porządkującą operacje atomowe reprezentowane przez liście drzew. Relacja <0 może być uporządkowaniem częściowym. Jednak relacja ta musi być określona dla wszystkich par operacji, dla których zachodzi relacja konfliktowości CON0. Relacje częściowego porządku <i określające kolejność operacji na wyższych poziomach hierarchii transakcji są zdefiniowane następująco: operacja x poprzedza operację y w warstwie i wtedy i tylko wtedy, gdy wszyscy potomkowie operacji x poprzedzają wszystkich potomków operacji y. W przeciwnym wypadku operacje x i y są współbieżne. Uszeregowalność wielopoziomowa Na każdym poziomie abstrakcji można określić quasiporządek operacji < . Na poziomie 0 porządek ten określa ~i jedynie kolejność operacji konfliktowych, to jest: < = <0 ∩ CON0. ~0 Dla dowolnego wyższego poziomu i, dwie operacje f i g występują w zależności f < g, wtedy i tylko wtedy, gdy ~i mają potomków f’ i g’ na poziomie i-1, którzy są w relacji konfliktowej i f’ < g’. ~ i −1 Dla dwu poziomowego lasu, quasi-porządek < odpowiada ~i grafowi uszeregowalności transakcji. Stąd klasyczna teoria uszeregowalności może być traktowana jako szczególny przypadek uszeregowalności wielopoziomowej. Definicja Dana wielopoziomowa historia transakcji jest uszeregowalna, wtedy i tylko wtedy, gdy dla każdego poziomu lasu i, relacja < ∪ (<i ∩ CONi) jest acykliczna. ~i Uszeregowalność wielopoziomowa Dla danej wielopoziomowej historii transakcji jej uszeregowalność może być zweryfikowana poprzez próbę zwinięcia lasu do korzeni poszczególnych transakcji za pomocą operacji przestawiania węzłów i redukcji poziomów, w następujący sposób: • dla każdego poziomu, poczynając od poziomu 0, wyizoluj poddrzewa pod-transakcji przestawiając węzły niekonfliktowych operacji; • zredukuj wyizolowane poddrzewa do ich korzeni; Jeżeli jest możliwe zwinięcie lasu drzew do korzeni reprezentujących główne transakcje – wielopoziomowa historia jest uszeregowalna i jest równoważna uzyskanej historii sekwencyjnej. Przykład 1) Rozplątanie poddrzew w najniższej warstwie T2 T1 r2(r4) f2(q) r1(r1) f2(p) w1(r2 ← 3) w2(r3 ← 6) f1(p) s2(p) f1(p) s1(p) w2(r2 ← 4) f2(p) s2(p) przestawienie 2) Redukcja poziomów T1 r2(r4) r1(r1) T2 w2(r3 ← 6) w1(r2 ← 3) w2(r2 ← 4) redukcja f2(q) f1(p) f2(p) s2(p) f1(p) s1(p) f2(p) s2(p) 3) Rozplątanie poddrzew w kolejnej warstwie T1 r2(r4) T2 r1(r1) w2(r3 ← 6) przestawienie w1(r2 ← 3) w2(r2 ← 4) 4) Redukcja poziomów T1 r1(r1) T2 redukcja r2(r4) w1(r2 ← 3) w2(r3 ← 6) 5) Uszeregowalna historia wielopoziomowa T1 T2 w2(r2 ← 4) Ograniczenia modelu transakcji wielopoziomowych Struktura transakcji wielopoziomowych musi spełniać następujące wymagania: 1. Hierarchia abstrakcji – Transakcja jest hierarchią podtransakcji. Pod-transakcje w zależności od ich położenia w hierarchii (odległości od korzenia) należą do określonego poziomu abstrakcji. Pod-transakcje należące do określonego poziomu abstrakcji tworzą wyodrębnione warstwy transakcji. 2. Warstwy transakcji – Wyodrębnione warstwy są całkowicie hermetyczne. Pod-transakcje należące do warstwy n są kompletnie zaimplementowane przez podtransakcje warstwy n-1. 3. Regularność struktury hierarchii – Niedopuszczalne są wywołania między warstwami transakcji, które nie sąsiadują ze sobą. Atomowość transakcji wielopoziomowych Pod-transakcje bezpośrednio po ich zatwierdzeniu udostępniają wyniki swojej pracy. Zwiększa to stopień współbieżności transakcji. W związku z tym atomowość transakcji musi być zapewniona poprzez wykorzystanie transakcji kompensacyjnych. Reguła zatwierdzania. Pod-transakcja jest zatwierdzana niezależnie od jej transakcji rodzicielskiej. Jej zatwierdzenie odblokowuje użycie skojarzonej z nią transakcji kompensującej. Zatwierdzenie wszystkich transakcji rodzicielskich aż do korzenia drzewa nie ma żadnego wpływu na stan podtransakcji. Jeżeli jednak któraś z transakcji rodzicielskich z korzeniem drzewa transakcji włącznie zostanie wycofana, to spowoduje to uruchomienie transakcji kompensującej, która z definicji musi zostać zatwierdzona. Reguła wycofywania. Jeżeli transakcja (pod-transakcja) jest wycofywana to dla wszystkich jej pod-transakcji potomnych uruchamiane są transakcje kompensujące, które muszą zostać zatwierdzone. Uruchamianie transakcji kompensujących pod-transakcje jest rekurencyjnie stosowane do kolejnych niższych poziomów drzewa. Wycofywanie transakcji w korzeniu drzewa prowadzi do skompensowania wszystkich zatwierdzonych pod-transakcji. Zarządzanie współbieżnym wykonywaniem transakcji w obiektowych bazach danych Idea Złożone abstrakcyjne typy danych tworzą wielowarstwową architekturę bazy danych. Transakcje w na złożonych obiektach są naturalnymi hierarchiami pod-transakcji. Rolę pod-transakcji pełnią metody skojarzone z obiektami. Transakcje są, więc sekwencjami wywołań metod skojarzonych z obiektami, które rekursywnie wywołują metody obiektów składowych. Przykładowa baz danych • Baza danych jest zbiorem hermetycznych obiektów o strukturze hierarchicznej. • Wierzchołkiem tej hierarchii są obiekty typu Items reprezentujące produkty sprzedawane przez hurtownię. • Struktura obiektów typu Item obejmuje atrybuty atomowe reprezentujące: identyfikatory (ItemNo), nazwy (Name), ceny jednostkowe (Price) i stany magazynowe (QOH) poszczególnych produktów oraz atrybut wielowartościowy (Orders) reprezentujący zbiór złożonych zamówień na dany produkt. • Struktura obiektów typu Order obejmuje tylko atrybuty atomowe reprezentujące: identyfikator zamówienia (OrderNo), identyfikator zamawiającego (CustomerNo), wielkość zamówienia (Quantity) i status jego realizacji (Status). Items: set of Item ... Item ItemNo Name Price Orders: set of Order QOH ... Order OrdeNo Quantity CustomerNo Status Przykładowa baza danych Metody klasy Item • i → NewOrder (CustomerNo, Quantity) returns OrderNo – wstawia nowe zamówienie do zbioru zamówień produktu i, oraz ustawia status zamówienia na wartość new. • i → ShipOrder (OrderNo) – reprezentuje operację wysłania produktu i do klienta, poprzez zmniejszenie wartości atrybutu QOH o wielkość Quantity. • i → PayOrder (OrderNo) – reprezentuje operację opłacenia zamówienia i przez klienta. • i → TotalPayment () returns Money – oblicza całkowitą wartość wszystkich opłaconych zamówień na produkt i. Metody klasy Order • o → ChangeStatus (event) – zmień status zamówienia o przez ustawienie flagi event. Status zamówienia może być następujący: new, shipped, paid, shipped&paid. • o → TestStatus (event) returns Boolean sprawdza status zamówienia o i zwraca jedną z wartości true lub false. Metody atrybutów atomowych • a → Get ( ) - odczytuje wartość atrybutu a. • a → Put ( ) - modyfikuje wartość atrybutu a. Transakcja wielopoziomowa w obiektowej bazie danych BEGIN WORK . . i1→ShipOrder(o1) . . . . i2→ShipOrder(o2) . . . COMMIT WORK BEGIN WORK o1→ChangeStatus (shipped) i1(QOH) → Get( ) i1(QON) → Put( ) COMMIT WORK BEGIN WORK o1(status) → Get( ) o1(status) → Put( ) COMMIT WORK BEGIN WORK o2→ChangeStatus (shipped) i2(QOH) → Get( ) i2(QOH) → Put( ) COMMIT WORK BEGIN WORK o2(status) → Get( ) o2(status) → Get( ) COMMIT WORK Matryce kompatybilności Wywołanie metod f i g na tym samym obiekcie Item jest komutatywne wtedy i tylko wtedy, gdy dwie dowolne sekwencyjne realizacje zawierające metody f i g oraz dowolne inne metody obiektu Item są nierozróżnialne: • przez końcowy stan obiektu Item; • przez wartości zwracane przez metody f i g. Założenie: dostawa produktu jest niezależna od tego, czy zapłacono za zamówienie. Matryca kompatybilności metod obiektów klasy Item Item NewOrder (CustomerNo, ShipOrder PayOrder TotalPayment Quantity) (OrderNo) (OrderNo) → OrderNo NewOrder (CustomerNo, Quantity) → OrderNo OK konflikt konflikt OK ShipOrder (OrderNo) konflikt konflikt OK OK PayOrder (OrderNo) konflikt OK konflikt konflikt TotalPayment OK OK konflikt OK Matryca kompatybilności metod obiektów klasy Order Order ChangeStatus ChangeStatus TestStatus TestStatus (o, shipped) (o, paid) (o, shipped) (o, paid) ChangeStatus (o, shipped) OK OK konflikt OK ChangeStatus (o, paid) OK OK OK konflikt TestStatus (o, shipped) konflikt OK OK OK TestStatus (o, paid) OK konflikt OK OK Matryca kompatybilności metod atrybutów atomowych klas Item i Orders Atrybuty atomowe Get ( ) Put ( ) Get ( ) OK konflikt Put ( ) konflikt konflikt Transakcje wykonywane w przykładowej bazie danych Rozważanych będzie następujących pięć typów transakcji: T1: realizacja dwóch zamówień na dwa różne produkty dla danego klienta (dwukrotne wywołanie metody ShipOrder dla obiektów i1 i i2, z argumentami o1 i o2); T2: opłacenie przez klienta dwóch zamówień na dwa różne produkty (dwukrotne wywołanie metody PayOrder dla obiektów i1 i i2, z argumentami o1 i o2); T3: sprawdzenie realizacji dwóch zamówień jednego klienta na dwa różne produkty (dwukrotne wywołanie metody TestStatus na zamówieniach o1 i o2 z argumentem shiped); T4: sprawdzenie płatności dwóch zamówień jednego klienta na dwa różne produkty (dwukrotne wywołanie metody TestStatus na zamówieniach o1 i o2 z argumentem paid), T5: obliczenie ogólnej sumy wpłat dla wszystkich zamówień dotyczących danego produktu (wykonanie metody TotalPayment dla produktu i1) Podstawowy algorytm zarządzania współbieżnością transakcji Synchronizacja współbieżnych transakcji jest realizowana za pomocą algorytmu blokowania dwufazowego stosującego blokady semantyczne związane z poszczególnymi metodami klas. Blokady są zwalniane niezależnie przez każdą pod-transakcję. Ograniczenia Algorytm podstawowy jest poprawny, jeżeli spełnione są dwa założenia: • Wszystkie pary (f, g) potencjalnie konfliktowych metod znajdują się na tym samym poziomie drzewa swoich transakcji. • Dla każdej pary (f’, g’) przodków f i g, które znajdują się na tym samym poziomie drzewa swoich transakcji, f’ i g’ operują na tym samym obiekcie. Współbieżne wykonanie dwóch otwartych zagnieżdżonych transakcji T1 T2 ShipOrder(i1,o1) ChangeStatu (o1,shipped) Get (o1,status) Get (i1,QON) Put (o1,status) PayOrder(i1,o1) ChageStatus Put (o1,paid) (i1,QON) Get (o1,status) Put (o1,status) PayOrder(i2,o2) ChangeStatus (o2,paid) Get (o2,status) ShipOrder(i2,o2) ChangeStatus Get Put (o2,shipped) (i2,QOH) (i2,OOH) Put Get (o2,status) (o2,status) Put (o2,status) Niepoprawna realizacja Ominięcie hermetyczności obiektu Item T1 T3 ShipOrder(i1,o1) ShipOrder(i2,o2) ChangeStat(o1,shipped) Get(i1,QOH) Put(i1,QOH) TestStat(o1,ship) TestStat(o2,ship) Get(o1,status) Put(o1,status) Get(o1,status) Get(o2,status) ChangeStat(o2,shipped) Get(o2,status) ... Put(o2,status) Algorytm synchronizacji transakcji w obiektowych bazach danych Struktury pomocnicze Dla każdej blokady l: • identyfikator obiektu, na której została założona; • lista parametrów aktualnych wywołania metody; • identyfikator transakcji / pod-transakcji, która założyła lub czeka na założenie blokady l. Dla każdej transakcji / pod-transakcji t: • uporządkowana lista wszystkich przodków pod-transakcji t; • zbiór wszystkich transakcji / pod-transakcji, które blokują transakcję / pod-transakcję (waits-for-sets). procedure exec-transaction (t) begin /* faza zakładania blokad */ for all s in t.children do s.waits-for-set := empty for all locks h założonych lub czekających na założenie na obiekcie s.object do b := test-conflict (h, s) if b ≠ nil then dodaj b do s.waits-for-set fi od if s.waits-for-set is not empty then kolejkuj żądanie blokowania s.object; czekaj na zakończenie wszystkich transakcji/pod-transakcji ze zbioru s.waits-for-set; fi załóż blokadę na s.object exec-transaction (s) od /* faza akceptacji */ for all s in t.children do usuń s ze wszystkich waits-for-sets innych transakcji/pod-transakcji if t.parent ≠ nil then zamień blokadę s na blokadę utrzymaną fi od if t.parent = nil then /* koniec transakcji głównej */ zwolnij wszystkie blokady fi end exec-transaction function test_conflict(h,r) returns tid /* Testuje zgodność metod h i r. Dla kompatybilnych blokad zwraca wartość nil. Dla niekompatybilnych przodka transakcji h, na którego zakończenie musi czekać transakcja r. */ begin if h and r są kompatybilne or r and h należą do tej samej transakcji głównej then return nil fi for all h’ in h.ancestor_chain do for all r’ in r.ancestor_chain do if h’ and r’ są kompatybilne then if h’ is zatwierdzona then return nil else return h’ /* r musi czekać na zakończenie h’ / fi fi od /for all r’ / od /for all h’ / return h.root /* w najgorszym przypadku r musi czekać na zakończenie głównej transakcji h */ end test-conflict Konflikt między komutatywnymi i zatwierdzonymi przodkami T1 T4 ShipOrder(i1,o1) ShipOrder(i2,o2) ChangeStat(o1,shipped) Get(i1,QOH) Put(i1,QOH) TestStat(o1,paid) TestStat(o2,paid) Get(o1,status) Put(o1,status) Get(o1,status) Get(o2,status) ChangeStat(o2,shipped) Get(o2,status) ... Put(o2,status) Konflikt między komutatywnymi, ale nie zatwierdzonymi przodkami T1 T5 ShipOrder(i1,o1) ChangeStatus(o1,shipped) TotalPayment(i1) Get(i1,QOH) Get(o1,status) Put(o1,status) ShipOrder(i2,o2) Get(i1,price) Put(i1,QOH) Get(o1,status) Get(o1,quantity) ... ... Konflikt rozwiązany przez komutatywnych i zatwierdzonych przodków komutatywny i zatwierdzony przodek T1 T4 ShipOrder(i1,o1) ShipOrder(i2,o2) … ChangeStat(o1,shipped) Get(i1,QOH) Put(i1,QOH) TestStat(o1,paid) TestStat(o2,paid) ChangeStat(o1,shipped) Get(o1,status) Put(o1,status) Get(o1,status) Get(o2,status) Get(o2,status) Put(o2,status) Konflikt rozwiązany przez komutatywnych i niezatwierdzonych przodków komutatywny i niezatwierdzony przodek ShipOrder(i1,o1) T1 T5 TotalPayment(i1) ShipOrder(i2,o2) … ChangeStat(o1,shipped) Get(i1,QOH) Get(o1,status) Put(o1,status) … Put(i1,QOH) Get(o1,status) Get(o1,quantity) ChangeStat(o1,shipped) Get(o2,status) Put(o2,status) Wykonanie przesunięte w czasie