Üdvözlöm Önöket. Vladislav Rodin vagyok. Jelenleg az OTUS „Magas terhelésű architektúra” kurzusának vezetője vagyok, és szoftverarchitektúrával foglalkozó kurzusokon tanítok.
A tanítás mellett, ahogy azt már észlelhették, szerzői anyagokat írok az OTUS blogjához a Habr-on, és a mai cikket a kurzusunk indításához szeretném kapcsolni. , amelyre jelenleg felvételt hirdetünk.

Bevezetés
A amelyről beszéltünk, a tranzakciók szerepe az adatbázisokban a hibás működések elkerülésére és az adatok párhuzamos hozzáférésének biztosítására irányult. Ahhoz, hogy ezeket a feladatokat teljes mértékben elvégezzük, a tranzakciónak ACID tulajdonságokkal kell bírnia. Ma részletesebben beszélünk az I (izoláció) ezen rövidítésben.
Elszigetelés
Az izoláció a párhuzamos környezetben való adathozzáférés problémáját oldja meg, lényegében védelmet nyújt a race condition-ök ellen. Ideálisan az izoláció a sorba állítást jelenti, vagyis egy olyan jellemzőt, amely biztosítja, hogy a párhuzamosan végrehajtott tranzakciók eredménye megegyezzen azzal, mintha azok sorozatban futottak volna. A probléma ezen jellemzővel az, hogy műszakilag nagyon nehezen megvalósítható, ami következtében jelentősen befolyásolja a rendszer teljesítményét. Éppen ezért az izolációt gyakran gyengítik, elfogadva bizonyos anomáliák bekövetkezésének kockázatát, amelyről a következőkben beszélni fogunk. Az anomáliák kialakulásának lehetősége éppen az, ami jellemzi a tranzakciók izolációs szintjét.
A legismertebb anomáliák a következők: dirty read, non-repeatable read, phantom read, de valójában még 5 létezik: dirty write, cursor lost update, lost update, read skew, write skew.
Dirty write
Az anomália lényege abban rejlik, hogy a tranzakciók felülírhatják a nem elkötelezett adatokat.

Ez az anomália nemcsak azért veszélyes, mert az adatok ütközhetnek a tranzakciók mindkét elkötelezése után (ahogyan az a képen is látható), hanem azért is, mert megsérti az atomaritást: mivel megengedjük, hogy felülírjuk a nem elkötelezett adatokat, nem világos, hogyan lehet visszagörgetni egy tranzakciót anélkül, hogy a másikra is hatással lennénk.
Az anomáliát viszonylag egyszerűen kezelhetjük: írás előtt zárolást alkalmazunk, megakadályozva más tranzakciók számára, hogy a feljegyzést módosítsák, amíg a zárolás fel nem oldódik.
Dirty read
A dirty read az elkötelezetlen adatok elolvasását jelenti.

Problémák merülnek fel, amikor a mintavétel alapján valamilyen műveleteket kell végrehajtani vagy döntéseket kell hozni.
Az anomália kijavításához olvasási zárolást lehet alkalmazni, de ez jelentősen befolyásolja a teljesítményt. Sokkal egyszerűbb azt mondani, hogy a tranzakció rollbackeléhez az adat kezdeti állapotának (a felvitel előtt) szükségszerűen meg kell maradnia a rendszerben. Miért ne olvasnánk onnan? Ez elég olcsó, ezért a legtöbb adatbázis alapértelmezetten eltávolítja a dirty read-et.
Elveszett frissítés
Az elveszett frissítés elveszett frissítéseket jelent, és a fordítás elég pontosan tükrözi a probléma lényegét:

Valójában a T2 tranzakció eredménye visszavonásra került. Ilyen helyzetet nyílt vagy rejtett zárolásokkal lehet megoldani. Tehát vagy egyszerűen csak frissítjük a rekordot, és akkor rejtett zárolás lép fel, vagy végrehajtjuk select for update, ami olvasási és írási zárolás keletkezését idézi elő. Vegye figyelembe, hogy ez a művelet meglehetősen veszélyes: a "bűnös" olvasásunk blokkolja a többi olvasást. Néhány adatbázis biztonságosabb select for share, amely lehetővé teszi az adatok olvasását, de nem engedélyezi a módosításokat.
Kurzor elveszett frissítés
Finomabb ellenőrzés érdekében az adatbázisok más eszközöket is kínálhatnak, például kurzorokat. A kurzor egy olyan struktúra, amely egy sor halmazt tartalmaz, és lehetővé teszi azok bejárását. declare cursor_name for select_statement. A kurzor tartalmát a select határozza meg.
Miért van szükség kurzorra? Azért, mert egyes adatbázisok zárolást kínálnak az összes rekordra, amelyet a select választott ki (read stability), vagy csak arra a rekordra, amelyen a kurzor éppen áll (cursor stability). A cursor stability rövid zárolást hajt végre, ami lehetővé teszi a zárolások számának csökkentését, ha nagy adatmennyiséget járunk be. Ezért az elveszett frissítést a kurzor esetén külön kiemelik.
Nem megismételhető olvasás
A nem megismételhető olvasás abban rejlik, hogy a tranzakciónk végrehajtása során 2 egymást követő olvasás ugyanarról a rekordról különböző eredményekhez vezet, mert egy másik tranzakció közbeavatkozott a két olvasás között, megváltoztatta az adatainkat, és elkötelezte azt.

Miért is lenne ez probléma? Képzelje el, hogy a T2 tranzakció célja a képen az összes olyan termék kiválasztása, amelynek ára kevesebb, mint 150 egység. Valaki más 200 egységre emelte az árat. Így a beállított szűrő nem működik.
Az adatok anomáliái megszűnnek, ha kéthetes zárlatokat adunk hozzá, vagy ha MVCC mechanizmust használunk, amiről szeretném külön megemlíteni.
Fantoms olvasás
Fantoms olvasásnak nevezzük azokat az adatokat, amelyeket egy másik tranzakció hozzáadott.

Például megfigyelhetjük a legolcsóbb termék hibás lekérdezését, amikor ez az anomália bekövetkezik.
A fantoms olvasásoktól való megszabadulás már elég nehéz. A hagyományos zárlatok nem elegendőek, hiszen nem tudjuk zárolni azt, ami még nem létezik. A 2PL rendszerek prediktív zárlatokat használnak, míg az MVCC rendszerek a tranzakció tervrajzát törlik, amelyeket megszakíthat a beszúrás. Az első és második mechanizmus is elég nehézkes.
Read skew
A read skew akkor jelentkezik, amikor több táblával dolgozunk, amelyeknek az adatai összhangban kell, hogy változzanak.
Tegyük fel, hogy vannak táblák, amelyek a bejegyzéseket és azok metaadatokat reprezentálnak:

Az egyik tranzakció olvas a táblákból, a másik módosítja őket:

A T1 tranzakció végrehajtása után a bejegyzés title = Good, a updated_by = T2, ami bizonyos eltérést jelent.
Valójában ez non-repeatable read, de több táblán belül.
A megoldás érdekében a T1 blokkolhatja az összes sorozatot, amelyet olvasni fog, ami megakadályozza, hogy a T2 tranzakció módosítsa az információt. MVCC esetén a T2 tranzakciót törlik. Ennek az anomáliának a védelme fontos lehet, ha kurzorokat használunk.
Write skew
Ezt az anomáliát szintén egyszerűbb példával magyarázni: tegyük fel, hogy a rendszerünkben legalább egy orvosnak ügyeletben kell lennie, de mindketten úgy döntöttek, hogy lemondják az ügyeletüket:


Az anomália oda vezetett, hogy egyik orvos sem öltözik fel ügyeletre. Miért történt ez? Mert a tranzakció olyan feltételt ellenőrzött, amelyet egy másik tranzakció megszakíthatott, és az elszigeteltség miatt nem láttuk ezt a változást.
Ez ugyanaz a non-repeatable read. Alternatívaként a select lekérdezések zárlatokat alkalmazhatnak ezeken a bejegyzéseken.
A write skew és a read skew a korábbi anomáliák kombinációi. A write skew lényegében phantom read. Vegyünk például egy táblázatot, amelyben szerepelnek a dolgozók nevei, a fizetésük és a projekt, amin dolgoznak:


Ennek eredményeként a következő kép állt elő: minden menedzser úgy gondolta, hogy a változtatásaik nem vezetnek költségtúllépéshez, ezért személyi változtatásokat hajtottak végre, amelyek összességében túllépéshez vezettek.
A probléma keletkezésének oka pontosan ugyanaz, mint a phantom read esetében.
Következtetések
Az adatbázis tranzakciós szintjének csökkentése a biztonság és a teljesítmény közötti kompromisszum, ezért ennek a szintnek a megválasztásakor figyelembe kell venni a potenciális üzleti kockázatokat, amelyek különböző anomáliák esetén felmerülhetnek.
Forrás: habr.com
