chce zarezerwować to samo miejsce na ten sam rejs na dany dzień i o zbliżonej porze; tę sytuację przedstawiono na rys. 7.9. Obaj powodują wykonanie instrukcji z wiersza 9) w tej samej chwili, a obie kopie zmiennej rez otrzymują wartość 0, ponieważ w bieżącej chwili miejsce nie jest zarezerwowane. W wierszu 12) w obu przypadkach zostaje podjęta decyzja o zarezerwowaniu tego miejsca i ustawieniu wartości atrybutu Rezerwacja na 1. Następują dwie modyfikacje bazy danych, jedna po drugiej, i obaj klienci otrzymują potwierdzenie rezerwacji na to samo miejsce w tym samym rejsie.
Klient 1 znajduje wolne miejsce
czas
Klient 2 znajduje wolne miejsce
Klient 1 rezerwuje miejsce zajęte
Klient 2 rezerwuje miejsce zajęte
RYSUNKK 7.9
Dwóch klientów próbuje jednocześnie zarezerwować lo samo miejsce
□
Jak widać z przykładu 7.11, może się zdarzyć, że dwa działania zostaną poprawnie wykonane, ale wynik ostateczny nie jest poprawny: obaj klienci wierzą, że dokonali rezerwacji. Takich kłopotliwych sytuacji można uniknąć, stosując zawarty w systemie SQL mechanizm, który służy do szeregowania wykonywania wywołań funkcji. Mówimy, żc wykonanie funkcji tej samej bazy danych jest uszeregowane, jeśli wykonanie każdej uruchomionej funkcji musi być zakończone, zanim zostanie uruchomiona inna funkcja. Mówimy także, że przetwarzanie jest sekwencyjne, jeśli funkcje zachowuje się tak, jakby odbywały się sekwencyjnie, nawet jeśli faktycznie nakładają się na siebie w czasie.
Oczywiście, jeśli wywołania funkcji Rezerwacja {) są uszeregowane (lub sekwencyjne), to nie dojdzie do błędu przedstawionego powyżej. Najpierw bowiem wykona się jedno wywołanie funkcji. Jej użytkownik odnajdzie wrolnc miejsce i zostanie ono dla niego zarezerwowane. Dopiero potem zostanie uruchomione drugie wywołanie tej funkcji, ale to miejsce będzie już zarezerwowane. Oczywiście któryś z użytkowników będzie zawiedziony, ale pod względem prawidłowości działania systemu jest ważne tylko to, że miejsce zostało przydzielone tylko jednej osobie.
Obok sytuacji nieuszeregowanych wykonań funkcji, która występ gdy dwa działania na bazie danych wykonują się w tym samym czasie, n się zdarzyć również, że w wyniku pojedynczego działania wystąpi nieoc2 wany stan bazy danych wówczas, gdy podczas wykonywania nastąpi a\\ sprzętu lub oprogramowania. Poniższy przykład stanowi dobrą ilustracje t co może się stać w takim przypadku. Podobnie jak poprzedni przykład, je sytuacja wyłącznie hipotetyczna i w praktycznie działających komercyji systemach baz danych takie błędy nie występują, chyba że program użytk jest niepoprawny.
1) EXEC SQL BEGIN DECLARE SECTION;
2) int kontol, kcnto2; /* dwa konta */
3) int saldol; /*kwota na pierwszym koncie*/
4) int kwota; /* kwota przelewu */
5) EXEC SQL END DECLARE SECTION;
6) void przelew () {
7)
/* kod w C, który służy do wprowadzenia kont i konta 2 oraz kwoty przelewu do zmienn kontol, korito2 oraz kwota */
3)
9)
10)
11)
12)
13)
14)
15)
16) 17)
18}
EXEC 5QL SELECT saldo JNTO :saldol EROM Konta
WHERE numer Kont a - :kontol; if (saldo! >= kwota) {
EXEC SQL UPDATE Konta
SET saldo = saldo + :kwota WHERE numerKonta = :konto2; EXEC SOL UPDATE Konta
SET saldo = saldo - :kwota WHERE numerKonta = :kontol;
1
else /* Koc w C, który drukuje komunikat
o tym, że nie można wykonać przelev ze względu na zbyt niskie saldo*/
)
RYSUNEK 7.10
Przelew pieniędzy z pewnego konta na inne
PRZYKŁAD 7.12
Rozważmy kolejny, popularny rodzaj baz danych: obsługę kont bankov Zasadnicza relacja nazywa się Konta i ma dwa atrybuty: NrKonta oraz .•