Názor k článku Transakce a izolace transakcí v databázích od Lael Ophir - Nepochopil jste článek? Zkusme to znovu, třeba to...

  • Článek je starý, nové názory již nelze přidávat.
  • 13. 5. 2009 18:23

    Lael Ophir (neregistrovaný)
    Nepochopil jste článek? Zkusme to znovu, třeba to půjde.

    Provádíme následující dotaz:

    BEGIN
    SELECT sum(castka) FROM aktiva;
    SELECT sum(castka) FROM pasiva;
    COMMIT

    Zároveň na serveru probíhá vkládání dat tímto způsobem (předpokládáme vždy shodu částek jdoucích na aktiva a pasiva):

    BEGIN
    INSERT INTO aktiva (castka) VALUES (1234)
    INSERT INTO pasiva (castka) VALUES (1234)
    COMMIT

    Při úrovni izolace READ UNCOMMITED "vidí" SELECT i data z neuzavřených transakcí. Proto se může stát, že uvidíte vloženo těch 1234 v tabulce aktiva, ale ještě nebude totéž vloženo do tabulky pasiva. Pozmínka: také se může stát, že transakce měnící obsah tabulky neskončí potvrzením (COMMIT) ale zrušením (ROLLBACK), a vy jste data přesto uviděl a načetl. To bývá také nežádoucí.

    Při úrovni izolace READ COMMITED vidíte jen data z potvrzených (commited) transakcí. Proto bude součet aktiv a pasiv vždy stejný. Problém je vyřešen. Jenže... Naše transakce se SELECTy provádí čtení dvěma dotazy. Může to dost dobře dopadnout to takhle:
    1. prvním SELECTem vypočtete sumu z tabulky aktiva (a suma z tabulky pasiva bude v tu chvíli stejná)
    2. pak někdo jinou transakcí aktualizuje tabulky aktiva i pasiva
    3. Vypočtete sumu z tabulky pasiva, ale už tam budete mít započtené změny učiněné v kroku 2. Aktiva v tuhle chvíli budou opět sedět s pasivy, ovšem hodnoty už budou dávno odlišné. Oops, pořád máme problém.

    Co s tím? Naštěstí tu máme úroveň izolace SERIALIZABLE. Na téhle úrovni izolace se DB tváří, jako kdyby byla vždy vykonána celá transakce, a teprve poté začala další transakce (což řeší náš problém popsaný v u READ COMMITED).
    Typická implementace úrovně SERIALIZABLE vypadá tak, že (navíc proti nižším úrovním izolace) transakce provádíte najednou, ale při čtení si zamknete záznamy v DB. Když se je pak někdo snaží změnit, jeho transakce musí čekat, dokud není zámek odstraněn. Pokud transakce na zámek nenarazí, může být uskutečněna. Asi není třeba říkat, že práce se zámky je pro dospělou DB s hromadami transakcí probíhajících v jednom čase klíčovou záležitostí.

    Mohli bychom si povídat ještě o snapshotech (verzování polí DB a řešení konfliktů až při commitu), příčinách a řešeních deadlocků (třeba wait-for graph), třífázovém commitu (používá se v heterogenních a distribuovaných systémech), a spoustě dalších krásných věcí. Jenže na to nemám čas, a navíc je sdílení vědomostí obtížné a nevděčné.

    Pro vaši informaci teoretické základy pro vznik RDBMS byly položeny Edgarem Coddem někdy v sedmdesátých letech, a implementace se začaly šířit v letech osmdesátých. Na začátku Coddova práce mohla působit jako neškodná akademická hříčka. Dnes na ní stojí veliký kus IT světa.

    Pokud chcete více informací, sežeňte si dokumentaci k MS SQL Serveru. Koncepty jsou tam vysvětlené tak, že to musí být jasné i slepému. Alternativou jsou skripta, wikipedia nebo učebnice.