Transakcje w Redis (za pośrednictwem MULTI/EXEC) grupują wiele poleceń do wykonania atomowo — wszystkie razem bez przeplatania się z poleceniami innych klientów. W połączeniu z WATCH do optymistycznego blokowania, obsługują scenariusze wymagające spójności wielu operacji. Transakcje w Redis różnią się od transakcji SQL na ważne sposoby.
MULTI / EXEC — kolejkowanie i wykonanie atomowe
MULTI # start a transaction (begin queuing commands)
SET account:1 100 # QUEUED (not executed yet)
SET account:2 200 # QUEUED
INCR counter # QUEUED
EXEC # execute ALL queued commands atomically (as one unit)
# → all commands run together, with NO other client's commands in between
MULTI rozpoczyna kolejkowanie poleceń; EXEC wykonuje je wszystkie atomowo (bez przeplatania się z innymi klientami). DISCARD anuluje kolejkowaną transakcję.
WATCH — optymistyczne blokowanie (check-and-set)
# WATCH a key; if it CHANGES before EXEC, the transaction ABORTS (returns nil)
WATCH balance
val = GET balance # read the current value
MULTI
SET balance (val - 100) # modify based on what we read
EXEC # → if "balance" changed since WATCH, EXEC fails (returns nil)
# → retry the whole thing if it failed (optimistic concurrency control)
WATCH zapewnia optymistyczne blokowanie: jeśli obserwowany klucz zostanie zmodyfikowany przez innego klienta przed EXEC, transakcja się przerywa — umożliwiając bezpieczne operacje check-then-set (ponowienie próby w przypadku konfliktu).
Jak transakcje w Redis RÓŻNIĄ SIĘ od SQL
⚠️ Redis transactions are NOT like SQL transactions:
✗ NO ROLLBACK — if a command fails at EXEC time, OTHER commands still execute
(errors don't roll back the transaction; Redis doesn't undo). Only syntax errors
before EXEC abort the whole thing.
✓ Atomicity = commands run together without interleaving (isolation), NOT all-or-nothing
with rollback on error.
→ Often Lua SCRIPTS are used instead for complex atomic logic (a script runs atomically).
Dlaczego to ważne
Rozumienie transakcji w Redis jest wartościowe dla wykonywania wielu operacji w spójny sposób, dlatego jest to użyteczna wiedza — a rozumienie, jak się różnią od transakcji SQL, jest szczególnie ważne, aby uniknąć błędnych założeń.
Główna możliwość — grupowanie poleceń MULTI/EXEC do wykonania atomowego (wszystkich razem, bez przeplatania się z poleceniami innych klientów) — rozwiązuje scenariusze, w których wiele operacji musi się wykonać jako spójna jednostka.
Mechanizm WATCH zapewnia optymistyczne blokowanie (check-and-set): przerwanie transakcji, jeśli obserwany klucz zmienił się przed EXEC, umożliwiając bezpieczne operacje check-then-modify (np. zmniejszenie salda na podstawie jego bieżącej wartości) z ponowieniem próby w przypadku konfliktu — ważne dla poprawnych operacji współbieżnych.
Najkrytyczniejszym punktem jest rozumienie, jak transakcje w Redis różnią się od transakcji SQL: Redis nie ma wycofywania — jeśli polecenie się nie powiedzie w momencie EXEC, pozostałe polecenia nadal się wykonują (Redis nie cofa), więc "atomowość" tutaj oznacza, że polecenia wykonują się razem bez przeplatania się (izolacja), a NIE wszystko-albo-nic z wycofywaniem błędu.
Błędne zrozumienie tego (zakładanie wycofywania jak w SQL) prowadzi do niepoprawnej obsługi błędów.
Wiedza, że skrypty Lua są często używane zamiast tego do złożonej logiki atomowej (skrypt wykonuje się atomowo jako jednostka) jest wartościowa.
Ponieważ spójna wielooperacyjna wykonanie i poprawna współbieżność są rzeczywistymi potrzebami, a transakcje w Redis (MULTI/EXEC z WATCH do optymistycznego blokowania) je rozwiązują, ale z ważnymi różnicami od SQL (brak wycofywania), które muszą być zrozumiane, zrozumienie transakcji w Redis — MULTI/EXEC, optymistyczne blokowanie oparte na WATCH, a zwłaszcza rozróżnienie braku wycofywania od SQL — jest wartościową, praktycznie istotną wiedzą do poprawnego używania Redis w scenariuszach współbieżnych, gdzie rozumienie różnic od znanych transakcji SQL jest tak samo ważne jak sam mechanizm.
