Transakcja to niepodzielna jednostka pracy w bazie danych: zestaw operacji, który wykonuje się w całości albo wcale. Jeśli cokolwiek pójdzie nie tak w trakcie, baza cofa wszystkie zmiany do stanu sprzed startu, jakby nic się nie wydarzyło. Dzięki temu dane nie zostają w połowicznym, niespójnym stanie — a o to właśnie chodzi.
Klasyczny przykład to przelew. Zdejmujesz 100 zł z konta A i dodajesz 100 zł do konta B. To dwie osobne operacje UPDATE, ale logicznie jedna całość. Gdyby pierwsza się udała, a druga padła (np. serwer się wyłączył w połowie), pieniądze wyparowałyby z systemu. Transakcja temu zapobiega: albo zaksięgują się obie zmiany, albo żadna.
Jak to działa
Transakcję otwierasz, wykonujesz operacje i na koniec ją zatwierdzasz (COMMIT) albo cofasz (ROLLBACK). Do momentu COMMIT zmiany są „tymczasowe” — inni użytkownicy zwykle ich nie widzą, a baza trzyma sposób na ich wycofanie.
Transakcje opisuje się skrótem ACID: Atomicity (wszystko albo nic), Consistency (baza przechodzi z jednego poprawnego stanu w drugi, reguły i constrainty zostają zachowane), Isolation (równoległe transakcje nie depczą sobie po danych) i Durability (po COMMIT zmiany przetrwają nawet zanik zasilania). To fundament, na którym stoją bazy relacyjne jak PostgreSQL, MySQL (silnik InnoDB) czy Oracle.
Przykład z praktyki
W PostgreSQL przez psql wygląda to tak:
BEGIN;— start transakcjiUPDATE konta SET saldo = saldo - 100 WHERE id = 1;UPDATE konta SET saldo = saldo + 100 WHERE id = 2;COMMIT;— zatwierdzenie obu zmian naraz
Jeśli między krokami zorientujesz się, że coś jest nie tak, wpisujesz ROLLBACK; i baza wraca do punktu wyjścia. Możesz też ustawiać SAVEPOINT, żeby cofać się tylko do wybranego momentu, a nie na sam początek.
Na co uważać
Pierwszy mit: „transakcja sama się zapisze”. Nie — bez COMMIT (albo autocommit, który wiele klientów ma domyślnie włączony) zmiany mogą zniknąć przy rozłączeniu. Drugi błąd to trzymanie transakcji otwartej godzinami — blokady (locks) na wierszach potrafią zablokować innych i wywołać deadlock. Trzymaj transakcje krótkie.
Trzecia pułapka: nie wszystko jest transakcyjne. W MySQL silnik MyISAM transakcji nie obsługuje, a w wielu bazach polecenia DDL (CREATE, DROP) potrafią niejawnie zatwierdzić bieżącą transakcję. Sprawdzaj, z czym pracujesz.
Pojęcia powiązane: ACID, COMMIT i ROLLBACK, poziomy izolacji (isolation levels), blokady i deadlock, dirty read, SAVEPOINT, spójność danych.