Nikdy nevíš, kdy to přijde
Zobrazit menu   MENU

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 se , nikdy nesmí nastat situce kdy se provede pouze část podúkolů. V takovém případě musí systém zajistit, aby se transakce "stornovala" a celý systém se uvedl do předchozího stavu.

Databá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ží indexy
18. Jak správně používat indexy
19. Transakce
20. Uložené procedury
21. Triggery