Termin 22 grudnia
Święty Mikołaj posiada na biegunie północnym magazyn słodyczy z którego co roku wysyła na cały świat paczki pełne pyszności. Przy obsłudze magazynu pracują elfy które obsługują magazyn z poziomu SQLa.
Elfy przygotowały bazę danych z zamówieniami, w której znajdują się cztery tabele:
slodycz_w_magazynie(nazwa, ilosc_pozostalych, CHECK(ilosc_pozostalych >= 0))
paczka(identyfikator, kraj, opis obdarowanego)
slodycz_w_paczce(identyfikator_paczki, slodycz, ilosc)
podobny_slodycz(ktory_slodycz_jest_podobny, do_czego_slodycz_jest_podobny, podobienstwo)
Przykłady:
slodycz_w_magazynie ('Czekolada Studencka', 100), ('Kasztanki', 1000)
paczka (1, 'Polska', 'Krzysztof Ciebiera'), (2, 'Polska', 'Krzysztof Stencel')
slodycz_w_paczce (1, 'Czekolada Studencka', 1), (1, 'Kasztanki', 10), (2, 'Czekolada Studencka', 3)
podobny_slodycz('Czekolada Studencka', 'Milka', 0.9)
Elfy kompletują paczki używając psql. Każdy elf dostaje kupkę listów do Mikołaja zawierających oczekiwane ilości słodyczy w paczkach i próbuje po kolei skompletować paczki. Jeśli jakiegoś towaru brakuje, to elf próbuje wybrać towar podobny. Kompletowanie paczki może być bardzo szybkie (sekundy) a może być bardzo wolne (godziny, bo elf w trakcie transakcji zrobił sobie przerwę). Elfy wykorzystują rozwiązanie, w którym sprawdzają najpierw czy jest wystarczająco dużo towaru w magazynie a potem go zamawiają. Przykładowa transakcja wygląda tak:
BEGIN;
-- tworzymy paczkę
INSERT INTO paczka (...) RETURNING id;
> 1 -- identyfikator paczki
-- sprawdzamy czy w magazynie jest wystarczająco dużo słodyczy z pierwszej pozycji na liście(Czekolada Studencka * 2)
SELECT ilosc_pozostalych FROM slodycz_w_magazynie WHERE nazwa = 'Czekolada Studencka';
> 1
-- nie ma dwóch czekolad, więc sprawdzamy do czego jest podobna czekolada studencka
SELECT .... FROM podobny_slodycz...
> Milka, 0.9
-- sprawdzamy czy jest wystarczająco dużo Milki w magazynie
SELECT id, ilosc_pozostalych FROM slodycz_w_magazynie WHERE nazwa = 'Milka';
> 20 -- liczba Milek w magazynie
-- dodajemy do zamówienia dwie milki i zmniejszamy stan w magazynie
INSERT INTO slodycz_w_paczce (1, 'Milka', 2);
UPDATE slodycz_w_magazynie SET ilosc_pozostalych = ilosc_pozostalych - 2 WHERE nazwa = 'Milka';
-- przechodzimy do kolejnej pozycji w liście
....
COMMIT; -- czasem ROLLBACK
-- przechodzimy do kolejnego listu do Mikołaja
W trakcie transakcji elf może się zorientować, że nie da się skompletować paczki, robi wtedy ROLLBACK, odsyła list do szefa i przechodzi do kolejnego listu do Mikołaja. Elfy zauważyły, że niekiedy system zawiesza się na poleceniu UPDATE, niekiedy zaś wywala się, bo ilość_pozostałych spada poniżej zera.
Pomóż elfom usprawnić ich system optymalizując co najmniej dwa sprzeczne kryteria:
Liczba transakcji zrealizowanych na sekundę.
Liczba transakcji zakończona niepowodzeniem.
Przeprowadź eksperymenty i przygotuj raport który pozwoli wybrać elfom najlepsze dla nich rozwiązanie. Oceniany będzie między innymi zestaw pytań, na które można odpowiedzieć w oparciu o raport (czyli czy nie zapomnieliśmy o czymś ważnym).
Mamy 20 elfów.
Elf w jednym przedziale czasu pracuje nad jedną i tylko jedną paczką i albo udaje mu się ją skompletować, albo musi odesłać list do szefa.
Manipulować można treścią transakcji od słowa BEGIN do COMMIT albo ROLLBACK.
Nie możemy przemodelować tabeli, ale możemy dodać inne tabele.
Listy odesłane do szefa nie powracają.
Przerwy mogą być w dowolnym miejscu transakcji i należy wymyślić złośliwego adwersarza.
Każdy elf przygotowuje paczkę i najpóźniej w momencie gdy robi COMMIT, dowiaduje się czy mu się udało czy nie.
TBD