Popis úrovní izolace

Dokončeno

PostgreSQL má tři úrovně izolace transakcí, které brání třem typům konfliktů souběžnosti, špinavé čtení, neopakovatelné čtení a přízrakové čtení.

Typy konfliktů souběžnosti

Zašpiněná čtení

Špinavé čtení nastane, když jedna transakce čte aktualizovanou verzi dat, kterou upravuje jiná transakce. Tato aktualizace však není nikdy potvrzena.

Například transakce probíhá na účtu úspory, který by vzal zůstatek účtu na méně než nulu. Před potvrzením transakce se zkontroluje zůstatek účtu a transakce se vrátí zpět, protože účty úspor nesmí mít zůstatek menší než nula. Současně se spouští sestava, která zobrazuje aktuální zůstatek všech účtů úspor. Pokud jsou povolená zašpiněná čtení, vrátí se záporný zůstatek, i když se nikdy nevrátí.

Neopakovatelné čtení

K neopakovatelnému čtení dochází v případě, že transakce: čte data, další transakce aktualizuje data a počáteční transakce znovu čte data a uvidí nové aktualizace.

Například Připojení A spustí transakci a přečte náklady na jednotku a počet jednotek pro objednávku, což jsou náklady 10 a počet jednotek 3. Připojení B pak spustí další transakci a aktualizuje stejnou objednávku, aby se nastavily náklady na jednotku na 12. Ve stejné transakci jako původní dotaz vypočítá připojení A celkové náklady na objednávku. Pokud jsou povolená neopakovatelná čtení, vrátí připojení A náklady na jednotku 10, počet jednotek 3 a celkové náklady na 36, což samozřejmě nemá smysl.

Fantomové čtení

Přízrakové čtení nastane, pokud transakce: čte data, další transakce přidá do dat nový řádek (nebo řádky) a počáteční transakce znovu přečte data a uvidí nové aktualizace.

Připojení A například spustí transakci a spočítá celkový počet faktur za den v Paříži. Celkový počet 1 100 faktur za všech 10 obchodů v Paříži. Připojení B pak spustí další transakci a přidá novou maloobchodní prodejnu v Paříži s 200 fakturami za otevírací den nového obchodu. V transakci Connection A teď systém spočítá počet obchodů k výpočtu počtu faktur na obchod. Připojení A by teď dělilo 1 100 transakcí o 11 obchodů místo původního 10, které existovalo při spuštění dotazu na počet faktur. Tento výpočet teď vrátí nesprávný průměr 100, i když v novém úložišti bylo 200 faktur, které transakce Connection A neúčtovala ve svém průměrném výpočtu.

Úrovně izolace

Azure Database for PostgreSQL má tři úrovně izolace transakcí, potvrzené čtení, opakovatelné čtení a serializovatelné. Nepotvrzené čtení není dostupné ve službě Azure Database for PostgreSQL.

Vliv úrovní izolace na konflikty souběžnosti:

Úroveň izolace Špinavé čtení Neopakovatelné čtení Přízrakové čtení
Nepotvrzené čtení* Možný Možný Možný
Potvrzené čtení Není možné Možný Možný
Opakovatelné čtení Není možné Není možné Možný
Serializovatelný Není možné Není možné Není možné

* V PostgreSQL není k dispozici

Potvrzené čtení je výchozí úroveň izolace ve službě Azure Database for PostgreSQL. Potvrzení čtení je nejvhodnější pro většinu scénářů, protože zabraňuje nezašpiněných čtení a zároveň poskytuje dobrý výkon. Je možné mít neopakovatelné čtení a fantomové čtení, ale tyto podmínky mohou nastat pouze v případě, že existují více příkazů SELECT současně dotazující stejná data.

Opakovatelné čtení se liší od potvrzení čtení, protože více příkazů SELECT v rámci transakce by vidělo stejné výsledky, i když jiná transakce aktualizovala řádky mezi spuštěním dvou příkazů SELECT transakce. Pokud jiná transakce vloží nové řádky, tyto řádky se nezobrazí ve výsledcích druhého příkazu SELECT.

Serializovatelná úroveň izolace poskytuje nejvyšší úroveň izolace transakcí a provádí, jako by různé transakce byly spuštěny v sériovém, to znamená jeden za druhým. Nevýhodou úrovně serializovatelné izolace je, že pokud transakce provádí aktualizaci, ostatní transakce by ji mohly blokovat. Serializovatelná transakce musí čekat na dokončení blokující transakce, což má vliv na výkon.

Serializovatelné transakce také nemohou provádět změny v žádné řádky, které ostatní transakce upravovat během serializovatelné transakce. Pokud dojde ke konfliktu této formy, vrátí se chybová zpráva, a proto je důležité, aby při použití serializovatelných transakcí byla do aplikací integrovaná logika opakování.

Chcete-li aktualizovat úrovně izolace transakcí, použijte příkaz TRANSACTION ISOLATION LEVEL v rámci transakce.

Příklad:

BEGIN TRANSACTION
TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SELECT * FROM humanresources.department
COMMIT;