|
![]() | Izolace transakcí | ![]() | Transakce a body návratu | Příkaz START TRANSACTION | ![]() |
Kombinování dvou odlišných mechanismů synchronizace požadavků různých klientů - explicitního zamykání a nastavení izolace transakcí - může vést k blokování klienta nebo k vrácení chyby.
Nechť jeden klient zamkne pro přepis záznam Z a druhý klient položí dotaz, při jehož zodpovídání je nutno testovat hodnoty ze záznamu Z.
Pokud druhý klient má nastavenou úroveň izolace transakcí SERIALIZABLE, pak je vytváření odpovědi na dotaz pozastaveno do doby, než první klient odemkne záznam Z nebo dokud nevyprší limit doby čekání na zámek. Požadavek na vytvoření dotazu pak skončí v druhém případě chybou.
Pokud dotaz má takovou strukturu, že dovoluje odložené vytváření, pak k chybě dojde až tehdy, když se testuje hodnota ze záznamu Z.
Proč první klient blokuje druhého klienta? První klient má díky zámku pro přepis vyhrazeno právo kdykoli změnit obsah záznamu Z. Druhý klient nastavením izolace SERIALIZABLE žádá, aby server zaručil, že opakované položení stejného dotazu dá vždy stejnou odpověď. Jelikož se hodnoty záznamu Z používají při vyhodnocení dotazu, server toto zaručit nemůže. Proto nemůže povolit zodpovězení dotazu druhého klienta, dokud první klient vlastní zámek. Situace má za následek čekání nebo chybu, podle nastavených provozních parametrů.
Problém lze demonstrovat na tomto příkladu:
Máme tabulku STRTAB vytvořenou příkazem CREATE TABLE STRTAB (S CHAR(12)). Tabulka má jeden sloupec S obsahující řetězec znaků, bez indexů. Tabulka nechť obsahuje alespoň jeden záznam.
Model programu Lock:
... zamkni_tabulku_pro přepis(StrTab); otevři_modální_okno; odemkni_tabulku_pro přepis(StrTab); ...
Model programu Select:
... nastav_izolaci_transakcí(3); otevři_kursor('select * from Strtab where s<''zzzzz''') spočítej_záznamy_v_kurzoru; zavři_kurzor; ...
První klient nejprve spustí program Lock a nechá jej čekat se zobrazeným modálním oknem. Pak druhý klient spustí program Select. Tento program se dostane do stavu čekání na zámek (stav 3 v přehledu klientů na serveru).
Pokud zavřením modálního okna první klient pokračuje dál a odstraní zámek, pak druhý klient vzápětí dokončí vytváření kurzoru a také skončí bez chyby.
Pokud první klient neodstraní zámek v časovém limitu, pak druhý klient skončí s chybou NOT_LOCKED (136) - "S objektem někdo pracuje".
K vzájemnému blokování klientů v tomto případě nedojde, pokud druhý klient bude používat úroveň izolace transakcí 1 (READ COMMITTED).
![]() | Izolace transakcí | ![]() | Transakce a body návratu | Příkaz START TRANSACTION | ![]() |