DB Lock: Typy zámků (Lock Modes) a jejich kompatibilita

V minulém díle jste si mohli při procházení obrázků vztahujících se k jednotlivým příkladům všimnout sloupce Request Mode. V tomto sloupci se zobrazily požadavky na zámky jednotlivých objektů, které byly vzneseny probíhající transakcí. Dnes se budeme věnovat bližšímu popisu jednotlivých typů zámků.

Typy zámků

Shared (S)

Tento typ zámku umožňuje číst data více transakcím zároveň. Jsou-li řádky uzamknuty tímto zámkem, nemůže druhá transakce modifikovat takto uzamknuté řádky. Zámek je uvolněn jakmile je dokončeno čtení. Toto chování lze změnit pomocí Transaction Isolation Level nebo Hintu.

Update (U)

Jedná se o speciální druh zámku. Tento druh zámku je použit pro vyhledání sad dat, které se budou měnit a u kterých má být zabráněno dalším změnám. Jakákoliv jiná transakce, která bude chtít zamknout data pro změnu nebo jiným exkluzivním zámkem, bude odsunuta k čekání na dokončení stávájící operace.
Jinými slovy tento druh zámku může pomoci při řešení vzájemně zablokovaných transakcí (deadlock), které jsou způsobeny konverzí Shared (S) zámku na Exclusive (X) zámek.

Exclusive (X)

Tento druh zámku se používá pro všechny modifikace pomocí INSERT, UPDATE a DELETE. Zámek se používá v případech, kdy je potřeba zabránit souběžným transakcím, aby pracovaly se zamknutými daty. Všechny ostatní zámky tedy musí čekat na dokončení současné operace a na uvolnění zámku. Nicméně existuje možnost, jak přečíst i tato zamknutá data, kterému se říká Dirty Reads. V některém z následujících dílu se k tomuto termínu ještě vrátím.

Intent (I)

Intent zámky se používají k označení nadřazeného objektu, jehož nižší část je zamknuta např. Shared (S) nebo Exclusive (X) zámkem. Je to z toho důvodu, aby například dvě transakce nechtěly uzamknout jednu tabulku na dvou různých vrstvách. Pokud si první transakce T1 uzamkne řádek a druhá transakce T2, která započala později než T1, si chce uzamknout celou tabulku, pak musí T2 počkat na dokončení T1. V rámci lock hierarchie se umisťují zámky odshora dolů. Nejprve tabulka dostane IX zámek a nenastane-li žádná chyba, pak se teprve zamykají řádky zámkem X.

Intent Shared (IS)

Označuje existenci Shared (S) zámků na nižší úrovni lock hierarchie.

Intent Exclusive (IX)

Označuje existenci Exclusive (X) zámků na nižší úrovni lock hierarchie.

Shared with intent exclusive (SIX)

Nastane-li v rámci jedné transakce případ, kdy si např. SELECT zamkne stránku (S) zámkem a zároveň dojde u UPDATU řádku při zamknutí řádku (X) zámkem, pak na stránce bude aplikován SIX zámek.

Intent update (IU)

Objevuje se na stránkách, které mají označené řádky (U) zámkem.

Shared intent update (SIU)

Zámek je aplikován na stránce, která je zamknutá v rámci jedné transakce např. SELECTem, který zamyká stránku pomocí hintu UPDLOCK a druhý SELECT uzamyká stejnou stránku pomocí hintu PAGLOCK.

Update intent exclusive (UIX)

Podobně jako výše uvedené kombinace, tento zámek se skládá z U a IX zámku.

Schema Stability Lock (Sch-S)

V momentě, kdy je spuštěn dotaz, který vyžaduje vytvoření a zkompilování plánu, je aplikován Sch-S zámek. Tento zámek umožňuje ostatním transakcím manipulovat s daty, nicméně nedovoluje měnit strukturu schématu např. smazáním tabulky, přidáním či odebráním sloupce v tabulce, atp.

Schema Modification Lock (Sch-M)

Jakmile se mění např. struktura tabulky, je aplikován Sch-M zámek. Jedná se o nejvíce omezující zámek, který není kompatibilní s ostatními zámky. Brání tedy ostatním transakcím k přístupu k objektu.

Bulk Update (BU)

V případě, že je potřeba efektivně manipulovat s větším množstvím dat v tabulce, používají se BULK operace. Nad tabulkou je aplikován BU zámek, který zabezpečí, že ostatní procesy, které se nepodílejí např. na nahrávání dat do tabulky, nebudou mít k tabulce přístup. BU zámek je kompatibilní sám se sebou, tudíž proces, který nahrává data obvykle pro větší efektivitu vytvoří více vláken, která mohou souběžně zapisovat do tabulky.

Key-Range (R)

Představme si, že potřebujeme načíst nějakou sadu dat, kterou budeme procházet v nějaké aplikaci a zároveň nechceme, aby nám nějaká cizí transakce vkládala nové řádky spadající do našeho načteného rozsahu. Přesně k tomuto slouží zámky pracující s rozsahy dat.

Kompatibilita zámků

V předchozí části jsme si představili typy zámků. Z textu lze vytušit, že nutně musí existovat nějaká pravidla, která určují jak jsou spolu jednotlivé typy zámků kompatibilní. Stejně jako v běžném životě, přijede-li současně více aut na křižovatku, musí existovat pravidla, jež určují která auta mají přednost, která auta mohou křižovatkou projet současně, případně která auta musí zastavit a počkat na průjezd ostatních vozidel.

MS SQL Server Lock Compatibility Matrix

Tabulka kompatibility zámků se nazývá Complete Lock Compatibility Matrix a je dostupná na https://technet.microsoft.com/en-us/library/ms186396(v=sql.105).aspx

V příštím díle se podíváme blíže na Eskalaci zámků.