Rozdział ten w całości będzie
poświęcony operowaniu na relacyjnych danych oraz niebezpieczeństwu jakie
występuje podczas takich operacji. Dowiemy się, jak zapobiegać przypadkom
wycieku danych lub błędom podczas operowania na zasobach repozytorium.
Aby nie opowiadać o abstrakcyjnych procesach, podam kilka przykładowych
operacji, które mogą zaburzyć spójność całego systemu i doprowadzić do jego
błędnego działania. Książkowy przykład zastosowania transakcji to przelew
bankowy. Jeśli chcemy zapłacić za zakupy w sklepie, system informatyczny musi
dokonać następujących czynności:
- sprawdzić, czy stan twojego konta pozwala na dokonanie
zakupu
- pobrać odpowiednią kwotę z twojego konta
- przekazać pobraną sumę i przesłać ją na konto sklepu
Najważniejsze w tym wszystkim jest to, że jeśli któraś z
powyższych operacji się nie powiedzie musimy powrócić do stanu sprzed
rozpoczęcia operacji.
Innym technicznym przykładem
jest proces wstawiania danych. Przypuśćmy, że obsługujemy bazę danych operatora
telefonii komórkowej. Robimy rozliczenie miesięczne i podliczanie kosztów dla
poszczególnego użytkownika z danego miesiąca. Operacja na tak ogromnym zasobie
danych może trwać parę godzin. I w pewnym momencie komputer się zawiesza. Co
się dzieje z danymi? Czy dane przeliczone zostały już wstawione? A jak zostały
wstawione - czy poprawnie? Oba powyższe przykłady powinny mieć status
dwuwartościowy. Albo się w pełni poprawnie wykonały, albo w całości zostają
odwołane. Do tego właśnie służy transakcja. Do odwołania wszystkich operacji,
na które została nałożona.
Teraz, kiedy troszeczkę wyjaśniłem, czym jest transakcja przejdźmy do
formalnego jej zdefiniowania.
Definicja transakcji
Transakcja jest jednostką wykonywania, w której wszystkie polecenia
są wykonane poprawnie lub w przeciwnym przypadku nie jest wykonywane żadne z
poleceń. Jest to sekwencja operacji wykonywanych jako jedna logiczna jednostka
pracy.
Każda z transakcji tworzona
jest z zachowaniem pewnych standardowych własności:
Własności transakcji
Atomic – transakcja
jest najmniejszą jednostką logiczną. Znaczy to, że jest wykonywana w całości
albo w całości jest odwołana
Consistent –
transakcja nie zmienia spójności bazy. To znaczy, że jeśli baza była spójna
przed wykonaniem transakcji, będzie też spójna po jej ukończeniu.
Isolated – transakcja
musi być izolowana, czyli nie może wchodzić w konflikty z innymi transakcjami
wykonywanymi na tym samym zbiorze danych
Durable - transakcja jest trwała, jeżeli
gwarantowane jest, że wykonane działania pozostaną kompletne bez względu na to,
co się stanie z bazą po poprawnym zakończeniu transakcji. Jeżeli wystąpi awaria
zasilania i serwer bazy danych ulegnie awarii, istnieje gwarancja, że
transakcja będzie kompletna po ponownym uruchomieniu serwera.
Aby zagwarantować spójność bazy
i mieć pewność, że wykonywane operacje zakończą się sukcesem lub porażką,
stosowany jest mechanizm blokowania. Blokady są gwarancją tego, że podczas
operowania na danych przez jedną transakcję dane nie zostaną zmienione bądź usunięte.
Rozpoczęcie transakcji na SQL Server 2005 można
dokonać na trzy sposoby:
Explicite – jawne rozpoczęcie transakcji za
pomocą polecenia BEGIN TRANSACTION
Autocommit – automatyczne, operacje na
serwerze standardowo podlegają transakcjom. Każde z poleceń jest automatycznie
zatwierdzane po poprawnym wykonaniu. Nie ma wtedy potrzeby commitowania
transakcji.
Implicit – niejawne, wywoływane przez programy
użytkowe działające na bazie danych.
Zakończenie transakcji odbywa się za pomocą poleceń COMMIT
lub ROLLBACK. Polecenia COMMIT używamy, gdy
wszystkie operacje od rozpoczęcia transakcji powiodły się. W takiej sytuacji
możemy zatwierdzić wszystkie zmiany, jakie zostały wprowadzone. Polecenie to
dodatkowo zdejmuje wszystkie blokady z tabel, które zostały zablokowane na czas
trwania transakcji.