19. Transakce
Transakce je v informatice hojně užívaný výraz. Co přesně znamená v kontextu databází? Zjednodušeně je o provedení určitého úkolu (složeného z jednotlivých podúkolů) tak byla zachována integrita databáze (data zástala konzistentní). Hlavním smyslem je, aby seDatabáze MySQL transakce podporuje již dlouhou dobu, pokud je ale chceme využít, musí být naše tabulky typu InnoDB. MyISAM které jsme využívaly v předchozích dílech tutoriálu transakce nepodporují.
ACID
Transakce by měly splňovat takzvaná ACID pravidla. Tato zkratka ze složena z počátečních písmen 4 vlastností správné transakce:- atomicita - znamená že se operace provede celá, nebo vůbec. Neexistuje možnost že se provede pouze část
- konzistence - transakce nenaruší integritu databáze
- izolovanost - pokud beží více transakcí zároveň, neovlivňují se
- trvalost - změny provedené transakcí jsou trvale uložené
Asi nejčastějším příkladem, na kterém se demonstrují transakce jsou bankovní účty. Představme si situaci, kdy v bance chceme převést nějaké penize z jednoho účtu na druhý. Taková akce je složena z více podčástí. Musí se strhnout správná částka z odchozího účtu, uložit záznam o převodu a připsat peníze na příchozí účet.
A teď si představme že se vše neprovede jako jedna transakce, ale postupně jako série jednotlivých akcí. Odečtou se peníze z odchozího účtu, pak ale dojde k technickému problému a další akce se již neprovedou. Z účtu odesílatele peníze zmizely, ale na druhém účtu nejsou - v podstatě se ztratily. Taková situace samozřejmě nikdy nesmí nastat a proto se na takové úkoly musí využít transakce.
Abychom si mohli transakce prakticky vyzkoušet, budeme si muset vytvořit nové tabulky (musí být typu innoDB).
CREATE TABLE `ucty` (
`ucet_id` int(10) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`klient` varchar(50) COLLATE utf8_czech_ci NOT NULL,
`aktualni_zustatek` float NOT NULL
) ENGINE=InnoDB;
INSERT INTO `ucty` (`ucet_id`, `klient`, `aktualni_zustatek`) VALUES
(1, 'Petr Novotný', 500),
(2, 'Lukáš Smrk', 2800),
(3, 'Tereza Černá', 3180.3);
CREATE TABLE `prevody` (
`prevod_id` int(10) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`z_uctu_id` int(10) NOT NULL,
`na_ucet_id` int(10) NOT NULL,
`castka` float NOT NULL
) ENGINE=InnoDB;
Nyní máme v naší databázi tabulku ucty, kde si vedeme záznamy o jednotlivých účtech - jaké je jméno vlastníka a aktuální zůstatek. V druhé tabulce prevody evidujeme jednotlivé převody částek mezi účty.
Užití transakcí
Samotná transakce se skládá z několika příkazů. Začneme klíčovými slovy START TRANSACTION, poté uvedeme samotné příkazy které chceme provést a celou transakci uzavíráme příkazem COMMIT. Vyzkoušíme si to na převodu mezi našimi účty:START TRANSACTION;
INSERT INTO prevody (z_uctu_id, na_ucet_id, castka) values (1, 2, 100);
UPDATE ucty SET aktualni_zustatek = aktualni_zustatek - 100 WHERE ucet_id = 1;
UPDATE ucty SET aktualni_zustatek = aktualni_zustatek + 100 WHERE ucet_id = 2;
COMMIT;
Z účtu s ID 1 jsme převedli částku 100 Kč na účet s ID 2, výši jednotlivých účtů jsme upravili a o celé operaci uložily záznam. Aktuální tabulka ucty bude nyní vypadat takto:
+---------+--------------+-------------------+ | ucet_id | klient | aktualni_zustatek | +---------+--------------+-------------------+ | 1 | Petr Novotný | 400 | | 2 | Lukáš Smrk | 2900 | | 3 | Tereza Černá | 3180.3 | +---------+--------------+-------------------+
Mezi otevírací a uzavírací příkaz transakce můžeme uvést libovolný počet příkazů včetně složitějších konstrukcí.
Příkaz ROLLBACK
V souvislosti s transakcemi je nutné uvést si ještě příkaz ROLLBACK. Ten slouží ke zrušení aktuální transakce nejčastěji v případě že došlo k nějaké chybě a je tedy třeba aktuální transakci stornovat. Existují příkazy, které ROLLBACK nezruší, jde zejména o definice struktur (CREATE, ALTER, DROP, ...).Přestože nám MySQL nevyhodí chybu, měli bychom vždy transakci uzavírat buď COMMIT nebo ROLLBACK, jinak se může stát že další operace skončí s neočekávanými výsledky.
Pakliže ve spolupráci s MySQL využíváte programovací jazyk PHP a k databázi přistupujete přes PDO, můžete využívat speciálních metod tohoto rozhraní, které práci s transakcemi zastřešují.
Další díly tutoriálu
17. K čemu slouží indexy18. Jak správně používat indexy
19. Transakce
20. Uložené procedury
21. Triggery