sql >> Databáze >  >> RDS >> PostgreSQL

Write Skew anomálie v Oracle a PostgreSQL nevrací transakci

V dokumentu z roku 1995 Kritika úrovní izolace ANSI SQL , Jim Gray a spol., popsali Phantom Read jako:

Phantom Read tedy neznamená, že můžete jednoduše vrátit snímek ze začátku aktuálně probíhající transakce a předstírat, že poskytnutí stejného výsledku pro dotaz vás ochrání před skutečnou anomálií Phantom Read.

V původní implementaci SQL Server 2PL (dvoufázové zamykání) vracení stejného výsledku pro dotaz implikovalo predikátové zámky.

Izolace snímku MVCC (Multi-Version Concurrency Control) (v Oracle nesprávně nazvaná Serializable) ve skutečnosti nebrání jiným transakcím ve vkládání/mazání řádků, které odpovídají stejným kritériím filtrování s dotazem, který již byl proveden a vrátil sadu výsledků v našem aktuálním běhu. transakce.

Z tohoto důvodu si můžeme představit následující scénář, ve kterém chceme uplatnit zvýšení platu pro všechny zaměstnance:

  1. Tx1:SELECT SUM(salary) FROM employee where company_id = 1;
  2. Tx2:INSERT INTO employee (id, name, company_id, salary) VALUES (100, 'John Doe', 1, 100000);
  3. Tx1:UPDATE employee SET salary = salary * 1.1;
  4. Tx2:COMMIT;
  5. Tx1:COMMIT:

V tomto scénáři generální ředitel spustí první transakci (Tx1), takže:

  1. Nejprve zkontroluje součet všech platů ve své společnosti.
  2. Oddělení HR mezitím provádí druhou transakci (Tx2), protože se jim právě podařilo najmout Johna Doea a dalo mu plat 100 000 $.
  3. Generální ředitel rozhodne, že navýšení o 10 % je proveditelné s ohledem na celkovou částku platů, aniž by si byl vědom toho, že se částka platů zvýšila o 100 000.
  4. Mezitím je HR transakce Tx2 potvrzena.
  5. Tx1 je potvrzeno.

Výložník! Generální ředitel přijal rozhodnutí o starém snímku a zvýšil tak, že současný aktualizovaný platový rozpočet nemusí unést.

Podrobné vysvětlení tohoto případu použití (se spoustou diagramů) si můžete prohlédnout v následujícím příspěvku .

Je toto Phantom Read nebo Napište Zkreslení ?

Podle Jima Graye a spol , jedná se o fantomové čtení, protože zkreslení zápisu je definováno jako:

V Oracle může nebo nemusí Transaction Manager detekovat výše uvedenou anomálii, protože nepoužívá predikátové zámky nebo zámky indexového rozsahu (zámky dalšího klíče) , jako je MySQL.

PostgreSQL dokáže zachytit tuto anomálii pouze v případě, že Bob provede čtení proti tabulce zaměstnanců, jinak se tomuto jevu nezabrání.

AKTUALIZACE

Zpočátku jsem předpokládal, že serializovatelnost bude také znamenat časové uspořádání. Jak však velmi dobře vysvětlil Peter Bailis , uspořádání nástěnných hodin nebo linearizace se předpokládá pouze u přísné serializace.

Proto byly mé předpoklady učiněny pro striktně serializovatelný systém. Ale to není to, co má Serializable nabídnout. Serializovatelný model izolace neposkytuje žádné záruky ohledně času a operace mohou být změněny, pokud jsou ekvivalentní nějakým sériové provedení.

Proto podle definice Serializable může k takovému Phantom Readu dojít, pokud druhá transakce nevyvolá žádné čtení. Ale v modelu Strict Serializable, který nabízí 2PL, by bylo fantomovému čtení zabráněno, i když druhá transakce neprovádí čtení proti stejným záznamům, které se snažíme chránit před fantomovým čtením.



  1. psql:FATAL:Ověření identity pro uživatele postgres selhalo

  2. CHARINDEX() vs PATINDEX() v SQL Server – jaký je rozdíl?

  3. Skrytá funkce:Přetahujte přístupové objekty mezi soubory

  4. Jak REGEXP funguje v MariaDB