Standard ANSI SQL definiuje cztery poziomy izolowania transakcji opisując je za pomocą występujących na każdym z tych poziomów fenomenów. SQL Server implementuje ten standard, ale, jak to z implementacjami bywa, niektóre zachowania tego serwera mogą nas zaskoczyć ….
2. MarcinSzeliga:Bio.ToString()
Piętnastoletnie doświadczenie
w pracy z serwerem SQL
Trener i konsultant
Autor książek i artykułów
Microsoft Most Valuable Professional
w kategorii SQL
Specjalista technologii Microsoft
3. Agenda
Standard ANSI SQL i opisane w nim
fenomeny
Fenomenalny poziom READ UNCOMMITED
Niespodzianki poziomu READ COMMITED
Bezpieczny poziom REPEATABLE READ ?
SERIALIZABLE vs SNAPSHOT
4. Standard ANSI SQL
Z czterech cech transakcji nas interesuje
poziom izolowania (I w ACID)
Czym jest i jak zmierzyć izolowanie?
Standard definiuje je za pomocą trzech
fenomenów:
Brudnych odczytów
Niepowtarzalnych odczytów
Odczytów – widm
Dodatkowo posiłkując się pojęciami
Utraty aktualizacji
Brudnego zapisu
5. Standard ANSI SQL
Podsumowanie i Demo
Poziom READ READ REPEATABLE SERIALIZABLE
izolowania UNCOMMITED COMMITED READ
P0 Brudne zapisy NIE NIE NIE NIE
P1 Brudne TAK NIE NIE NIE
odczyty
P2 TAK TAK NIE NIE
Niepowtarzalne
odczyty
P3 Utrata TAK TAK NIE NIE
aktualizacji
P4 Odczyty TAK TAK TAK NIE
widma
6. Fenomenalny poziom RU
RU sprowadza się do niezakładania
blokady współdzielonej na odczytywanych
zasobach ...
Dla serwera SQL oznacza on że w ogóle
nie interesuje nas spójność wyników, za
to chcemy otrzymać je jak najszybciej
Te same operacje mogą być
wykonywane w inny sposób
7. Fenomenalny poziom RU
Wiersze mogą być odczytane wielokrotnie
lub pominięte (DEMO)
Dlaczego ?
HoBT – fenomen dotyczy tylko BT
Strony BT tworzą dwukierunkową listę
Podczas aktualizacji danych strony mogą
być dzielone
Logiczny porządek stron != porządek
fizyczny
8. Fenomenalny poziom RU
Dlaczego ? c.d.
Dane mogą być odczytane w logicznej
kolejności stron (Index-order scan)
Albo w fizycznej kolejności stron (Allocation-
order scan)
W przypadku BT oznacza to skan indeksu z
opcją ORDERED = TRUE lub FALSE
9. Fenomenalny poziom RU
Co możemy zrobić?
Nie używać dyrektywy NOLOCK
Zablokować całą tabelę dyrektywą TABLOCK
Przełączyć grupę plików w tryb tylko do
odczytu
Przełączyć bazę do trybu READ COMMITED
SNAPSHOT
Zastosować własny mechanizm kontroli
sp_getapplock
…
10. Fenomenalny poziom RU
Zapytanie może skończyć się błędem
(DEMO)
Dlaczego ?
Zapytanie nie blokując pierwszej tabeli
oczekuje na odczytanie wiersza z drugiej
tabeli
Wybrany przez nie wiersz z pierwszej tabeli
zostaje usunięty
Nie ma z czym połączyć odczytanego po
zdjęciu blokady wiersza drugiej tabeli
11. Fenomenalny poziom RU
Co możemy zrobić?
Nie używać dyrektywy NOLOCK
Traktować błąd 601 podobnie do błędu 1205
Przełączyć bazę do trybu READ COMMITED
SNAPSHOT
Zastosować własny mechanizm kontroli
sp_getapplock
…
12. Niespodzianki poziomu RC
Domyślny poziom izolowania
Wiersze są blokowane na czas ich
odczytywania
Blokada współdzielona jest zdejmowana
natychmiast po odczytaniu wiersza
Nadal możemy pominąć oraz wielokrotnie
odczytać te same wiersze (DEMO)
13. Niespodzianki poziomu RC
Dlaczego ?
Po odczytaniu pierwszego wiersza zapytanie
zostało zablokowane
W międzyczasie odczytany już (pierwszy)
wiersz został zamieniony z nieodczytanym
wierszem trzecim
Po zdjęciu blokady odczytane zostały
pozostałe wiersze tabeli
Czyli pierwszy wiersz został odczytany
dwukrotnie, a trzeci - wcale
14. Niespodzianki poziomu RC
Podczas łączenia tabel możemy odczytać
poprzednią i bieżącą wersję tego samego
wiersza (DEMO)
Dlaczego?
Operator LOOP JOIN dwukrotnie odczytał
jedyny, w międzyczasie zmieniony wiersz
tabeli
15. Niespodzianki poziomu RC
To samo dotyczy pozostałych operatorów
i indeksów, możemy nawet naruszyć
więzy integralności (DEMO)
Dlaczego?
Operator HASH MATCH wyliczył wartości
mieszania dla wszystkich wierszy jednego
indeksu
Wykonał tą samą funkcję mieszania dla
pierwszego wiersza drugiego indeksu
W międzyczasie w jednym indeksie rekord
został zmodyfikowany
16. Niespodzianki poziomu RC
Co możemy zrobić?
Przełączyć bazę do trybu READ COMMITED
SNAPSHOT
Używać wyższych poziomów izolowania
transakcji
Zastosować własny mechanizm kontroli
sp_getapplock
…
17. Niespodzianki poziomu RC
W takim razie czy te same wiersze mogą
być wielokrotnie zaktualizowane przez
pojedynczą instrukcję UPDATE ? (DEMO)
Dlaczego?
Wbudowany mechanizm ochronny
„Hallowen Protection”
Włącza się automatycznie jeżeli zmienia się
fizyczna lokalizacja aktualizowanych
wierszy (np. podczas przyznawania
podwyżki przy indeksie na kolumnie Płaca)
18. Bezpieczny poziom RR ?
Odczytane wiersze pozostają
zablokowane do zakończenia transakcji
Dotyczy to również wierszy które nie trafiły
do wyniku zapytania
Wiersze które jeszcze nie zostały
odczytane nie są blokowane, a więc mogą
zostać pominięte (DEMO)
Mogą też pojawić się nowe wiersze które
powinny trafić do wyniku zapytania
19. Bezpieczny poziom RR ?
Dlaczego?
Po odczytaniu pierwszego wiersza zapytanie
oczekiwało na dostęp do zablokowanego
drugiego wiersza
W międzyczasie trzeci wiersz został
przeniesiony na początek tabeli
Co możemy zrobić?
Zastosować własny mechanizm kontroli
sp_getapplock
…
20. SERIALIZABLE vs SNAPSHOT
Na poziomie SERIALIZABLE na czas
trwania transakcji zakładane są blokady
typu Range
Odczytywane dane nie mogą zostać
zmodyfikowane, niemożliwe jest też
wstawienie nowych wierszy
Na poziomie SNAPSHOT na czas trwania
transakcji nie są zakładane żadne blokady
Odczytywane dane mogą zostać
zmodyfikowane, ale dla wcześniej
rozpoczętych transakcji te zmiany będą
niewidoczne
21. SERIALIZABLE vs SNAPSHOT
Wykonywanie transakcji na kopii danych
nie izoluje ich tak jak wykonywanie tych
samych transakcji jedna po drugiej
(DEMO)
Dlaczego?
Pierwsza transakcja zamienia białe pionki
czarnymi, druga – czarne białymi
Jeżeli będą wykonywane po kolei wszystkie
pionki będą albo czarne, albo białe
22. SERIALIZABLE vs SNAPSHOT
Dlaczego ? c.d.
Jeżeli będą wykonywane równocześnie, na
osobnych kopiach danych, zamienimy kolor
wszystkich pionków
Co możemy zrobić?
Pamiętać o tym