Databázové transakce jsou klíčovým prvkem pro zajištění integrity a spolehlivosti dat v moderních databázových systémech. Tento článek poskytuje komplexní rozbor databázových transakcí, SQL a architektur, které jsou nezbytné pro správu a zotavení dat, zejména v distribuovaném prostředí. Prozkoumáme základní vlastnosti, řízení souběžnosti, řešení problémů a praktické využití v SQL.
Co jsou databázové transakce? Základní shrnutí pro studenty
Transakce v databázi je logicky ucelená posloupnost operací, která převádí databázi z jednoho konzistentního stavu do jiného. Je to základní jednotka zotavení z chyb a souběžného zpracování. Pokud se všechny operace v transakci dokončí úspěšně, změny se trvale uloží. V opačném případě se všechny provedené změny vrátí zpět a databáze zůstane v původním stavu.
Klíčové vlastnosti transakcí (ACID)
Pro zajištění spolehlivosti a integrity dat se transakce řídí čtyřmi základními vlastnostmi, často označovanými jako akronym ACID:
- Atomičnost (Atomicity): Celá posloupnost operací je považována za jednu logickou jednotku. Buď se provede celá transakce, nebo se neprovede žádná její část. Pokud dojde k chybě, všechny změny se vrátí (ROLLBACK).
- Izolovaná vratnost (Isolation): Změny provedené transakcí nesmí být viditelné pro jiné transakce, dokud není globální transakce úspěšně dokončena (potvrzena). Izolace zabraňuje tomu, aby se chyby v jedné transakci šířily do dalších, nebo aby se navzájem ovlivňovaly souběžně běžící transakce. Efekt indukovaného vrácení se označuje jako řetězové vrácení (cascading rollback) nebo dominový efekt.
- Pernamentnost (Durability): Jakmile je transakce úspěšně potvrzena (COMMIT), provedené změny jsou trvale uloženy v databázi a nemohou být ztraceny ani v případě systémové chyby.
- Uspořádatelnost (Serializability): Výsledek souběžného zpracování transakcí musí být shodný s výsledkem, jako kdyby byly transakce provedeny sériově (jedna po druhé) v nějakém pořadí. To je obzvláště důležité v distribuovaných databázích.
Architektury databázových systémů a typy transakcí
V závislosti na rozsahu a umístění dat rozeznáváme různé typy transakcí a architektur.
Distribuované databázové systémy a globální transakce
Distribuovaný databázový systém se skládá z množiny uzlů propojených sítí, kde je globální databáze rozdělena na dílčí části alokované na různých uzlech. Globální transakce se zahajuje na jednom uzlu a podle potřeby se šíří do dalších uzlů. Rozpadá se na dílčí (lokální) transakce, které plní dílčí úkoly na příslušných uzlech. Tyto dílčí transakce jsou řízeny primární transakcí.
Moduly pro řízení transakcí v distribuovaných systémech
Součástí každého uzlu distribuovaného systému jsou klíčové moduly:
- Modul řízení transakcí: Zpracovává uživatelské požadavky, rozděluje transakce podle distribuce dat, sestavuje výsledky z dílčích transakcí a předává je uživateli.
- Modul řízení dat: Zodpovídá za čtení a zápis hodnot do lokální databáze a komunikaci s modulem řízení transakcí.
Lokální vs. globální transakce
- Lokální transakce: Potřebuje přístup k datům pouze na jediném uzlu a nevyžaduje spolupráci s jinými uzly.
- Globální transakce: Přesahuje rozsah jednoho uzlu a vyžaduje koordinaci mezi více uzly, kde se rozpadá na dílčí transakce.
Dvoufázový potvrzovací protokol (2PC): Řízení distribuovaných transakcí
Dvoufázový potvrzovací protokol (Two-Phase Commit Protocol) je základním mechanismem pro zajištění atomicity globálních transakcí v distribuovaných databázích. Cílem je, aby se všechny dílčí transakce buď potvrdily, nebo zrušily.
Fáze 1: Hlášení o připravenosti (Vote Phase)
- Primární transakce (koordinátor) odešle dotaz na všechny dílčí transakce, zda jsou připraveny k potvrzení.
- Každá dílčí transakce provede všechny své operace a dočasně uloží změny. Pokud je úspěšná, odešle koordinátorovi zprávu RC (Ready to Commit). Provedené změny ještě nezpřístupní pro další transakce.
- Pokud některá dílčí transakce selže nebo nemůže dosáhnout RC-bodu v daném časovém intervalu (time out), odešle zprávu ABORT.
Fáze 2: Fáze jištění (Commit Phase)
- Koordinátor primární transakce shromáždí všechna hlášení RC od dílčích transakcí.
- Pokud VŠECHNY dílčí transakce hlásily RC: Koordinátor vydá všem dílčím transakcím povolení k GLOBÁLNÍMU COMMITU. SŘBD se postará o skutečné uložení změn. Po tomto kroku mohou transakce zpřístupnit změny jiným transakcím.
- Pokud ALESPOŇ JEDNA dílčí transakce hlásila ABORT nebo nastal time out: Koordinátor vysílá ABORT všem dílčím transakcím. Celá globální transakce bude vrácena zpět.
Řešení výpadků uzlů při 2PC
Výpadky uzlů mohou nastat v různých fázích protokolu. Zde jsou klíčové situace a jejich řešení:
- Podtransakci nelze inicializovat: Primární transakce se pokusí iniciovat podtransakci na jiném uzlu. Pokud to není možné nebo původní uzel nahlásí RC (což by neměl), primární transakce odešle ABORT všem zúčastněným uzlům.
- Primární transakce neobdrží zprávu RC: Primární transakce neví, zda podtransakce selhala před RC-bodem nebo po něm. Vyšle zprávu ABORT všem zúčastněným podtransakcím.
- Lokální uzel není schopen informovat o RC-bodu: Podobné řešení jako výše, primární transakce vyšle ABORT.
- Primární transakce přijala RC/ABORT, ale nemůže zaslat globální zprávu: Primární transakce musí zůstat aktivní, dokud zprávu nedoručí. Pokud všechny podtransakce hlásily RC, čeká se na obnovení primární transakce. Pokud alespoň jedna hlásila ABORT, ostatní mohou provést lokální abort.
Synchronizace a řízení souběžnosti transakcí
Synchronizace je nezbytná pro správné řízení souběžně běžících transakcí. Zajišťuje, že operace jsou prováděny v takovém pořadí, aby byl výsledek shodný se sériovým rozvrhem.
Dvoufázový uzamykací protokol (2PL)
Základem synchronizace jsou uzamykací protokoly. Dvoufázový uzamykací protokol zajišťuje, že každý objekt, ke kterému je přistupováno, musí být nejprve uzamčen. Uzamykací modul přezkoumá tabulku zámků, zda nehrozí konflikt. Zámky platí do globálního COMMIT nebo ABORT.
- Centrální uzamykání: Jeden uzel udržuje centrální tabulku zámků pro všechny zúčastněné uzly. To umožňuje centrální rozpoznání uváznutí.
- Decentralizované uzamykání: Každý uzel vede vlastní tabulku zámků. To je méně náročné na komunikaci, ale ztěžuje rozpoznání globálního uváznutí.
Uváznutí (Deadlock) a jeho řešení
Uváznutí nastává, když transakce cyklicky čekají na uvolnění uzamčených objektů nebo jiných systémových zdrojů. Příkladem je situace, kdy transakce T1 drží zámek A a čeká na B, zatímco T2 drží B a čeká na A.
Rozpoznání uváznutí
Uváznutí se rozpoznává na základě čekacích grafů (wait-for graphs). Transakce jsou uzly grafu a vztahy „čekání na“ jsou orientované hrany. Nalezení kružnic v grafu indikuje uváznutí.
- Podněty ke zkoumání: Překročení čekací doby, odmítnutí požadavku na uzamčení, periodické zkoumání.
Vyhnutí se uváznutí pomocí časových razítek
Metody časových razítek předcházejí uváznutí přidělením časových razítek (TS) transakcím. Všechny dílčí transakce jedné globální transakce nesou časové razítko své primární transakce. Pokud transakce R požaduje zámek na objekt držený transakcí O, porovnají se jejich časová razítka:
- „Wait-Die“ metoda:
if TS(R) < TS(O) then wait else die(Mladší transakce zemře a vrátí se, pokud se pokusí uzamknout objekt starší transakce.) - „Wound-Wait“ metoda:
if TS(R) < TS(O) then wound else wait(Starší transakce „zraní“ mladší transakci, pokud drží požadovaný zámek, a mladší transakce se vrátí.)
Wait: Čekání na konec nebo přerušení transakce O. Die / Wound: Přerušení transakce R a její následné vrácení.
Transakce v SQL
V jazyce SQL je transakce posloupnost příkazů, která tvoří jednotku zotavení z chyb a souběžného zpracování. První příkaz v SQL implicitně zahajuje transakci.
Klíčové příkazy SQL pro řízení transakcí
- COMMIT: Normální ukončení transakce. Všechny změny jsou trvale uloženy v databázi.
SQL> COMMIT - ROLLBACK: Vrácení transakce. Všechny změny provedené od začátku transakce (nebo od posledního savepointu) se zruší a databáze se vrátí do předchozího stavu.
SQL> ROLLBACK - SAVEPOINT: Nastaví bod, k němuž lze transakci vrátit pomocí
ROLLBACK TO SAVEPOINT.SAVEPOINT nazev_bodu;Rollback k savepointu neuvolňuje LOG soubory. Rollback bez specifikace savepointu uvolňuje LOG soubory.
Zotavení z chyb: Jak fungují žurnály a algoritmy UNDO/REDO
Zotavení z chyby je proces obnovy konzistentního stavu databáze po selhání. Cílem je vrátit přerušené transakce, zopakovat potvrzené transakce a automaticky spustit vrácené transakce.
Žurnály (Log Files)
Žurnály jsou klíčové soubory, které uchovávají informace o průběhu transakcí a slouží k zotavení. Každý uzel sítě má svůj žurnál obsahující záznamy popisující celou historii transakcí (např. T, START; T, jméno_atributu, stará_hodnota, nová_hodnota; T, COMMIT).
Stavy transakce
Transakce se může nacházet v několika stavech:
- Aktivní (A): Od počátku provádění transakce.
- Částečně potvrzený (PC): Po provedení poslední operace transakce.
- Chybný (F): Nelze pokračovat v normálním průběhu transakce.
- Zrušený (AB): Po skončení operace ROLLBACK.
- Potvrzený (C): Po úspěšném vykonání COMMIT.
Kontrolní body (Checkpoints)
Kontrolní body jsou body tc, kdy se obsah vyrovnávacích pamětí odešle na disk a do žurnálu se zapíše kontrolní záznam. Ten obsahuje seznam všech transakcí, které byly v čase tc aktivní (započaly, ale nebyly potvrzeny).
UNDO / REDO algoritmus pro zotavení
Tento algoritmus je založen na bezprostředních aktualizacích databáze, kdy se databáze aktualizuje před dosažením stavu PC. Pro zotavení se využívá žurnál, kde každá změna musí být zaznamenána před aktualizací databáze.
Postup algoritmu:
- Vytvoří se dva seznamy: UNDO a REDO. UNDO obsahuje transakce z kontrolního bodu, REDO je prázdný.
- Žurnál se prohledává od
tcdopředu. - Při nalezení
START Tse transakce T přidá do seznamu UNDO. - Při nalezení
COMMIT Tse T přesune ze seznamu UNDO do REDO. - Na konci žurnálu jsou seznamy UNDO (nepotvrzené transakce) a REDO (potvrzené transakce, které je třeba zopakovat) kompletní.
Zotavení:
- UNDO seznam: Zpracování zpětným chodem v žurnálu (vrácení nepotvrzených změn).
- REDO seznam: Zpracování chodem vpřed (zopakování potvrzených změn).
Strategie odložené realizace změn (REDO algoritmus)
Alternativou je strategie odložené realizace změn, kdy se obsah bufferů přepíše na disk až po globálním commitu transakce. Nedosáhne-li transakce globálního commitu, změny na disku se neuskuteční. Do žurnálu se zapisují pouze nové hodnoty atributů pro chod vpřed. Tento přístup využívá tzv. REDO algoritmus.
Často kladené otázky (FAQ) k databázovým transakcím
Jaký je rozdíl mezi COMMIT a ROLLBACK v SQL?
COMMIT trvale uloží všechny změny provedené transakcí do databáze a ukončí ji. Databáze tak přejde do nového konzistentního stavu. Naproti tomu ROLLBACK zruší všechny změny provedené transakcí od jejího začátku (nebo posledního SAVEPOINTu) a vrátí databázi do původního stavu před transakcí. Žádné změny se tak neuloží.
Proč jsou důležité ACID vlastnosti transakcí?
ACID vlastnosti (Atomičnost, Izolace, Pernamentnost, Uspořádatelnost) jsou zásadní pro zajištění spolehlivosti, integrity a konzistence dat v databázových systémech. Bez nich by databáze byla náchylná k chybám, ztrátě dat, nekonzistentním stavům a problémům při souběžném zpracování, což by vedlo k nespolehlivým informacím a nefunkčnosti aplikací.
Co je to uváznutí a jak se mu databáze brání?
Uváznutí (deadlock) nastává, když dvě nebo více transakcí navzájem čekají na uvolnění zdrojů, které drží ty druhé, a nemohou tak žádná z nich pokračovat. Databáze se brání uváznutí pomocí rozpoznávacích mechanismů (např. čekací grafy pro detekci cyklů) a preventivních metod. Preventivní metody často zahrnují časová razítka (např. „Wait-Die“ nebo „Wound-Wait“ algoritmy), které určují, která transakce má čekat a která má být ukončena, aby se uváznutí předešlo.