Úroveň izolace transakcí

Aktuální verze stránky ještě nebyla zkontrolována zkušenými přispěvateli a může se výrazně lišit od verze recenzované 29. prosince 2019; kontroly vyžadují 20 úprav .

Úroveň izolace transakcí  je podmíněná hodnota, která určuje, do jaké míry v důsledku provádění logicky paralelních transakcíDBMS může přijímat nekonzistentní data. Škála úrovní izolace transakcí obsahuje řadu hodnot seřazených od nejnižší po nejvyšší; vyšší úroveň izolace odpovídá lepší konzistenci dat, ale její použití může snížit počet fyzicky paralelních transakcí. Naopak nižší úroveň izolace umožňuje více paralelních transakcí, ale snižuje přesnost dat. Volbou použité úrovně transakční izolace tedy vývojář informačního systému do určité míry poskytuje volbu mezi rychlostí práce a zajištěním zaručené konzistence dat přijímaných ze systému.

Problémy se souběhem pomocí transakcí

Pokud jsou transakce prováděny paralelně , mohou nastat následující problémy:

Zvažte situace, ve kterých mohou tyto problémy nastat.

Ztracená aktualizace

Situace, kdy při současné změně jednoho datového bloku různými transakcemi dojde ke ztrátě jedné ze změn.

Předpokládejme, že současně probíhají dvě transakce:

Transakce 1 transakce 2
UPDATE tbl1 SET f2=f2+20 WHERE f1=1; UPDATE tbl1 SET f2=f2+25 WHERE f1=1;

V obou transakcích se změní hodnota pole f2, po dokončení musí být hodnota pole zvýšena o 45. Ve skutečnosti může dojít k následujícímu sledu akcí:

  1. Obě transakce současně čtou aktuální stav pole. Přesný fyzický souběh zde není vyžadován, stačí, aby druhá operace čtení v pořadí byla dokončena dříve, než další transakce zapíše svůj výsledek.
  2. Obě transakce vypočítají novou hodnotu pole přičtením 20 a 25 k dříve načtené hodnotě.
  3. Transakce se snaží zapsat výsledek výpočtu zpět do pole f2. Protože je fyzicky nemožné provést dva zápisy současně, ve skutečnosti bude jedna z operací zápisu provedena dříve, druhá později. Druhá operace zápisu přepíše výsledek první operace.

V důsledku toho se hodnota pole f2 po dokončení obou transakcí může zvýšit ne o 45, ale o 20 nebo 25, to znamená, že jedna z transakcí měnících data „zmizí“.

"Špinavé" čtení

Čtení dat přidaných nebo upravených transakcí, která se později nepodaří potvrdit (rollback).

Předpokládejme, že máme dvě transakce otevřené různými aplikacemi, které provádějí následující příkazy SQL:

Transakce 1 transakce 2
UPDATE tbl1 SET f2=f2+1 WHERE f1=1;
SELECT f2 FROM tbl1 WHERE f1=1;
ROLLBACK WORK;

V transakci 1 se změní hodnota pole f2 a poté v transakci 2 se vybere hodnota tohoto pole. Poté je odvolána transakce 1. V důsledku toho se hodnota přijatá druhou transakcí bude lišit od hodnoty uložené v databázi.

Neopakované čtení

Situace, kdy se při opětovném čtení v rámci stejné transakce dříve přečtená data změní.

Předpokládejme, že existují dvě transakce otevřené různými aplikacemi, ve kterých se provádějí následující příkazy SQL :

Transakce 1 transakce 2
SELECT f2 FROM tbl1 WHERE f1=1;
UPDATE tbl1 SET f2=f2+3 WHERE f1=1;
COMMIT;
SELECT f2 FROM tbl1 WHERE f1=1;

V transakci 2 se vybere hodnota pole f2, poté se v transakci 1 změní hodnota pole f2. Pokud se znovu pokusíte vybrat hodnotu z pole f2 v transakci 2, bude získán jiný výsledek. Tato situace je zvláště nepřijatelná, když jsou data čtena za účelem jejich částečné úpravy a zapisování zpět do databáze.

Čtení "fantomů"

Situace, kdy při opakovaném čtení v rámci stejné transakce stejný výběr dává různé sady řádků.

Předpokládejme, že existují dvě transakce otevřené různými aplikacemi, které provádějí následující příkazy SQL:

Transakce 1 transakce 2
SELECT SUM(f2) FROM tbl1;
INSERT INTO tbl1 (f1,f2) VALUES (15,20);
COMMIT;
SELECT SUM(f2) FROM tbl1;

Transakce 2 provede příkaz SQL, který používá všechny hodnoty pole f2. Potom se do transakce 1 vloží nový řádek, což způsobí, že opětovné provedení příkazu SQL v transakci 2 přinese jiný výsledek. Tato situace se nazývá fantomové čtení (fantomové čtení). Od neopakovatelného čtení se liší tím, že výsledek opakovaného přístupu k datům se nezměnil v důsledku změny/smazání dat samotných, ale v důsledku výskytu nových (fantomových) dat.

Úrovně izolace

„ Úroveň izolace transakcí “ se týká stupně ochrany poskytované vnitřními mechanismy DBMS (tj. nevyžadující speciální programování) před všemi nebo některými z výše uvedených typů nekonzistencí dat, ke kterým dochází při paralelním provádění transakcí. Standard SQL-92 definuje škálu čtyř úrovní izolace: Čtení bez potvrzení, Čtení potvrzené, Opakovatelné čtení, Serializovatelné. První z nich je nejslabší, poslední je nejsilnější, každý další zahrnuje všechny předchozí.

Read uncommitted (čtení uncommitted data)

Nejnižší (první) úroveň izolace [1] . Pokud se několik paralelních transakcí pokusí upravit stejný řádek tabulky, bude mít poslední řádek hodnotu určenou celou sadou úspěšně dokončených transakcí. V tomto případě je možné číst nejen logicky nekonzistentní data, ale i data, jejichž změny ještě nebyly zaznamenány.

Typickým způsobem, jak implementovat tuto úroveň izolace, je uzamknout data během provádění příkazu change, což zajišťuje, že příkazy modifikace na stejných řádcích spuštěných paralelně jsou skutečně prováděny postupně a žádná ze změn se neztratí. Transakce pouze pro čtení se pod touto úrovní izolace nikdy neblokují.

Čtení potvrzeno (čtení pevných dat)

Většina průmyslových DBMS, zejména Microsoft SQL Server , PostgreSQL a Oracle , používá tuto úroveň ve výchozím nastavení. Na této úrovni je poskytována ochrana proti draftu, „špinavému“ čtení, nicméně během operace jedné transakce může být úspěšně dokončena další a jsou opraveny změny provedené v ní. V důsledku toho bude první transakce pracovat s jinou datovou sadou.

Implementace úplného čtení může být založena na jednom ze dvou přístupů: blokování nebo verzování.

Blokování čitelných a měnitelných dat. Spočívá v tom, že transakce zápisu zablokuje proměnlivá data pro transakce čtení pracující na úrovni potvrzené čtení nebo vyšší až do svého dokončení, čímž se zabrání „špinavému“ čtení a data zamčená transakcí čtení jsou uvolněna ihned po dokončení transakce. Operace SELECT (při dané úrovni izolace tedy může nastat situace „neopakovatelného čtení“). Ukládání více verzí řádků, které se mění paralelně. Při každé změně řádku DBMS vytvoří novou verzi tohoto řádku, se kterou transakce, která změnila data, nadále funguje, zatímco jakákoli jiná „čtená“ transakce vrátí poslední potvrzenou verzi. Výhodou tohoto přístupu je, že poskytuje větší rychlost, protože zabraňuje zablokování. Vyžaduje však ve srovnání s prvním výrazně větší množství paměti RAM, která se vynakládá na ukládání řadových verzí. Navíc, když více transakcí mění data paralelně, může to vytvořit situaci, kdy několik souběžných transakcí provede nekonzistentní změny stejných dat (protože neexistují žádné zámky, nic tomu nezabrání). Pak transakce, která se zapíše jako první, uloží své změny do hlavní databáze a zbývající paralelní transakce nebude možné potvrdit (protože to povede ke ztrátě aktualizace první transakce). Jediná věc, kterou může DBMS v takové situaci udělat, je vrátit zpět zbytek transakcí a vydat chybovou zprávu „Záznam již byl změněn“.

Konkrétní metodu implementace volí vývojáři DBMS a v některých případech ji lze přizpůsobit. MS SQL tedy standardně používá zámky, ale (ve verzi 2005 a vyšší) při nastavení parametru READ_COMMITTED_SNAPSHOT se databáze přepne na strategii verzování, Oracle zpočátku pracuje pouze podle verzovaného schématu. Informix můžete zabránit konfliktům mezi transakcemi čtení a zápisu nastavením konfiguračního parametru USELASTCOMMITTED (od verze 11.1), který způsobí, že transakce čtení obdrží poslední potvrzená data [2]

Opakovatelné čtení

Úroveň, na které transakce čtení „nevidí“, se mění na data, která dříve četla. Žádná jiná transakce přitom nemůže změnit data načtená aktuální transakcí, dokud neskončí.

Zámky ve sdíleném režimu jsou aplikovány na všechna data přečtená jakoukoli instrukcí v transakci a jsou držena, dokud není transakce dokončena. To zabrání jiným transakcím v úpravě řádků, které byly přečteny čekající transakcí. Jiné transakce však mohou vložit nové řádky, které odpovídají podmínkám vyhledávání pro pokyny obsažené v aktuální transakci. Když je příkaz restartován aktuální transakcí, budou načteny nové řádky, což povede k fiktivnímu čtení. Vzhledem k tomu, že sdílené zámky jsou drženy až do konce transakce, spíše než aby byly uvolněny na konci každého příkazu, je stupeň souběžnosti nižší než u úrovně izolace READ COMMITTED. Proto se obecně nedoporučuje zbytečně používat tuto a vyšší transakční úrovně.  

Serializovatelné

Nejvyšší úroveň izolace; transakce jsou od sebe zcela izolované, každá se provádí, jako by žádné paralelní transakce neexistovaly. Pouze na této úrovni souběžné transakce nepodléhají efektu „fantomového čtení“.

Podpora izolace transakcí ve skutečných DBMS

Transakční DBMS ne vždy podporují všechny čtyři úrovně a mohou také zavádět další. Při poskytování izolace existují také různé nuance.

Oracle tedy v zásadě nepodporuje nulovou úroveň, protože jeho implementace transakcí vylučuje „špinavá čtení“ a formálně neumožňuje nastavení opakovatelné úrovně čtení, to znamená, že podporuje pouze Read commited (ve výchozím nastavení) a Serializable. Zároveň na úrovni jednotlivých příkazů vlastně zaručuje opakovatelnost čtení (pokud příkaz SELECT v první transakci vybere sadu řádků z databáze a v tuto chvíli paralelní druhá transakce některé z těchto řádků změní, pak sada výsledků přijatá první transakcí bude obsahovat nezměněné řádky, jako by žádná druhá transakce nebyla). Oracle také podporuje takzvané transakce READ-ONLY, které jsou v souladu s Serializable, ale samy nemohou měnit data.

Microsoft SQL Server podporuje všechny čtyři standardní úrovně izolace transakcí a navíc úroveň SNAPSHOT, na které transakce vidí stav dat, která byla potvrzena před jejím spuštěním, a také změny, které sama provedla, to znamená, že se chová, jako by obdrželo spuštění snímku databázových dat a práci s nimi. Rozdíl oproti serializovanému je v tom, že se nepoužívají žádné zámky, ale v důsledku toho nemusí být potvrzení změn možné, pokud souběžná transakce dříve změnila stejná data; v tomto případě druhá transakce při pokusu o COMMIT vyvolá chybovou zprávu a bude zrušena.

Chování na různých úrovních izolace

"+" - zabraňuje, "-" - nebrání.

úroveň izolace fantomové čtení Neopakující se čtení "Špinavé" čtení Ztracená aktualizace [3]
SERIALIZAČNÍ + + + +
OPAKOVATELNÉ ČTĚNÍ - + + +
PŘEČTĚTE ODPOVĚDNĚ - - + +
PŘEČTĚTE NEZÁVAZNĚ - - - + [4]

Poznámky

  1. Pochopení úrovní izolace . Získáno 14. listopadu 2011. Archivováno z originálu 18. května 2012.
  2. konfigurační parametr USELASTCOMMITTED http://publib.boulder.ibm.com/infocenter/idshelp/v115/topic/com.ibm.adref.doc/ids_adr_0186.htm
  3. Pochopení dostupných úrovní izolace transakcí . Získáno 30. srpna 2012. Archivováno z originálu 14. října 2012.
  4. Paul Wilton, John Colby. Začátek SQL . — John Wiley & Sons, 2005-03-04. - S. 319. - 522 s. - ISBN 978-0-7645-9632-2 . Archivováno 22. dubna 2021 na Wayback Machine