DB Lock: Isolation Level

Microsoft SQL Server Logo

Stupeň vzájemného oddělení transakcí se nazývá Isolation Level a lze jím řídit:

  • zda-li při čtení dat mají být aplikovány zámky
  • jak dlouho jsou zámky aktivovány
  • v případě, že operace čtení se má provádět nad řádky, které jsou měněny druhou transakcí, isolation level řídí:
    • pozastavení čtení do doby, dokud řádky nejsou uvolněny ke čtení
    • zajištění čtení hodnot, které byly uloženy do databáze jinou transakcí pomocí COMMIT
    • případně lze přečíst i hodnoty, které ještě nebyly uloženy do databáze

Výběr isolation level nemá vliv na zámky, které jsou aplikovány při změně dat. Jakmile je třeba změnit data v tabulce, vždy je na měněný řádek aplikován exkluzivní zámek a uvolněn jakmile jsou data zapsány do databáze pomocí COMMITu. Nicméně pro čtení lze pomocí isolation level řídit dostupnost čerstvě změněných dat v průběhu transakce. Nastaví-li se isolation level benevoletně, více transakcí bude moci číst data i v průběhu jejich změny, za cenu nižší integrity dat. Je zde vyšší riziko, že budou přečteny hodnoty, které ve skutečnosti nemusí být vůbec zapsány do databáze např. vlivem selhání transakce při pokusu o nepovolený zápis do tabulky. Naopak nastaví-li se isolation level příliš přísně, omezí se souběžný přístup k datům. Může docházet k častějšímu vzájemnému blokování zapisujících a čtecích transakcí, ale současně se zvýší integrita dat.

READ COMMITTED

Tento typ je nastaven jako výchozí pro implicitní i explicitní transakce. Jak je již z názvu patrné, čtou se pouze data, která jsou uložena do databáze. Nehrozí tedy tzv. Dirty Reads. Díky zamykání řádků při čtení pouze na dobu nezbytně nutnou může docházet k Non-Repeatable Read nebo Phantom Read.

READ UNCOMMITTED

V případě, že chcete číst i data, která ještě nejsou uložena do databáze a ve výsledku ani nemusí být uložena, pokud transakce selže, můžete si nastavit tento isolation level. Důsledky použití této úrovně si můžete přečíst v Dirty Reads. Tato úroveň totiž nepoužívá zámky a tedy čtení není v kolizi ani s exkluzivními zámky ostatních transakcí.

REPEATABLE READ

Umožňuje při čtení zamknout řádky, držet je zamčené i po ukončení čtení a uvolnit je teprve až po skončení běžící transakce (COMMIT nebo ROLLBACK). Případně nedovoluje, aby byly přečteny data, které ještě nebyly uloženy transakcí do databáze. Pomocí této úrovně můžete předcházet jevu známému jako Non-Repeatable Read, ale naopak můžete způsobit Phantom Read.

SERIALIZABLE

Rozdíl oproti přechozí úrovni je ten, že jsou na řádky aplikovány zámky, které zamykají celý rozsah. Tedy pokud si zamknete nějaký rozsah, nelze do tabulky vložit nový řádek spadající do zamčeného rozsahu ani žádný řádek z rozsahu smazat. Zámky jsou uvolněny po ukončení transakce (COMMIT nebo ROLLBACK). Nemusíte se tedy bát Phantom Read, ale zároveň se radikálně snižuje dostupnost dat pro další transakce, což se může negativně projevit ve vyšším výskytu blokování ostatních transakcí.

SNAPSHOT

V principu umožňuje tato úroveň výrazně zvýšit souběžný přístup k datům tak, aby se minimalizovalo vzájemné blokování transakcí. Stinnou stránkou tohoto nastavení jsou zvýšené požadavky na výkon tempdb. Transakce při požadavku na čtení dat neaplikují Shared (S) zámek. Neblokují tedy transakce, které zapisují do tabulky. Platí to i naopak.