Typ tabulky InnoDB zvládá i další vlastnost a tou je tzv. transakční zpracování. Ve chvíli, kdy Vaše aplikace bude používat akční dotazy nad důležitými daty, jistě budete hledat způsob, jak tyto data co nejlépe ošetřit.

K tomu dobře poslouží transakce. Setkal jsem se i s názory, kteří transakční zpracování odsuzují z toho či onoho důvodu. Já, jako člověk, který tyto věci využívá v praxi mohu jen podotknout, že je to pro mě určitá záchrana při práci s akčními dotazy.

Co to je, to transakční zpracování dat? Jedná se způsob, pomocí kterého mohu své předešlé kroky navrátit zpět nebo je potvrdit. Série příkazu UPDATE, DELETE, INSERT, které jsou spuštěny při transakčním zpracování, se provedou tehdy, když uznám, že po změně nedojde k znehodnocení dat. Fyzicky se dané akce provedou až po úspěšném ukončení, do té doby jsou dočasně uloženy jen jako série příkazů, které čekají na ukončení. To sebou přináší i tu vlastnost, že zpracování může být v polovině přerušeno (např. výpadkem proudu) a přesto je možné dané úkony dokončit. Je jasné, že tuto vlastnost musíme brát s rezervou a neočekávat vždy spásnou pomoc od nedokončených transakcí. Tím mám na mysli, že se daná série příkazů již nikdy neprovede, nikoli, že by znehodnotila data.

Příkazy pro transakční zpracování jsou následující:
  • start transaction – spouští provedení transakčního zpracování
  • rollback – navrací veškeré změny a uvede data zpět do stavu před spuštěnou transakcí
  • commit – potvrzuje příkazy, zapisuje změny a uvolňuje systémové prostředky potřebné při transakci

Použití transakcí
Domnívám se, že je zbytečné zde vypisovat sérii nějakých akčních dotazu, kde na konci provedu commit či rollback. Spíše než to, je lepší malá ukázka v PHP, jak lze transakce smysluplně využít.

Příklad:

class Error
{
        private $error = array();

        public function __construct() {}

        public function addError($err)
        {
                if (!in_array($e­rr, $this->error)) {
                        $this->error[] = $err;
                }
        }

        public function isError()
        {
                return (boolean) count($this->error);
        }

}

$mysqli = new mysqli(/* connect /);
$error = new Error();

$mysqli->query(„start transaction“);

$query = „UPDATE uzivatele SET prijmeni = ‚Novák‘ WHERE login = ‚paveln‘“;
if ($mysqli->query($query) === false) {
        $error->addError($mys­qli->error);
}

/
dalsi akcni dotazy */

if (!$error->isError()) {
        $mysqli->query(„commit“);
} else {
        $mysqli->query(„rollbac­k“);
 }

Použil jsem zde záměrně vlastní jednoduchou třídu na kontrolu chyb. Je jasné, že příklad je pouze ilustrativní, ale potvrzení transakce mohu provést jedině ve chvíli, kdy jsem si jist, že to má data nijak neznehodnotí. Toto považuji za smysluplné použití transakčního zpracování, kdy pomocí nějaké vlastní aplikace budu rozhodovat, zda sérii příkazů zruším, či potvrdím.

Při práci s tabulkami při transakčním zpracování bychom si měli dát pozor zejména na příkaz: TRUNCATE TABLE, který vymaže data z tabulky a nastaví auto_increment na 1. Po provedení takového příkazu totiž není možné pomocí rollback získat data zpět.

Omezení existuje celá řada, k tomu doporučuji manuál a prostudovat samotné transakce tam.

Poslední věcí o které se zmíním je nastavení automatických transakcí. V souboru my.cnf nalezneme direktivu innodb_flush_log_­at_trx_commit, která pokud je nastavena na 1, provádí automaticky transakce. Toto chování se mi zdá nežádoucí a jako takové ho pro jistotu vypínám. Důvod proč něco takového dělám je rychlost aplikace. Pokud například vkládám velké množství dat, které není nijak zásadní pro běh aplikace a data mám zálohována, provedu úkon bez transakčního zpracování. Jednou ohromnou nevýhodou je totiž extrémní nárůst potřebných systémových prostředků.

Transakce byste měli používat s rozvahou, ale také se jich nebát, protože sebou přináší jistý komfort při modifikaci dat.

V příštím díle se budu věnovat triggerům a důvodům, proč něco takového využívat.