CodeGym /Kursy /SQL SELF /Zagnieżdżone transakcje: SAVEPOINT, ROLLBACK TO SAVEPOINT...

Zagnieżdżone transakcje: SAVEPOINT, ROLLBACK TO SAVEPOINT

SQL SELF
Poziom 53 , Lekcja 0
Dostępny

W PostgreSQL NIE MA prawdziwych zagnieżdżonych transakcji w takim klasycznym sensie. Jest tylko zewnętrzna transakcja i "warstwy" punktów zapisu w jej środku.

Termin "zagnieżdżone transakcje" w PostgreSQL zwykle oznacza użycie punktów zapisu (savepoints) przez komendy SAVEPOINT, ROLLBACK TO SAVEPOINT, RELEASE SAVEPOINT. To nie są osobne niezależne transakcje, tylko specjalne checkpointy w jednej zewnętrznej transakcji, do których możesz się cofnąć bez wycofywania wszystkiego.

Analogicznie do życia: piszesz długi tekst w edytorze i co jakiś czas robisz ctrl+s. Jak coś popsujesz, możesz wrócić do jednej z wcześniejszych zapisanych wersji, nie tracąc całego progresu.

Komendy do ogarniania punktów zapisu

Do zarządzania zagnieżdżonymi transakcjami PostgreSQL daje trzy główne komendy:

SAVEPOINT

Ta komenda służy do tworzenia "punktów zapisu", do których możesz się cofnąć, jak zajdzie taka potrzeba. Taki punkt działa jak checkpoint w naszej transakcji.

SAVEPOINT mypoint;

ROLLBACK TO SAVEPOINT

Cofa część zmian zrobionych po wskazanym punkcie, zostawiając wcześniejsze zmiany w tej samej zewnętrznej transakcji nietknięte.

ROLLBACK TO SAVEPOINT mypoint;

RELEASE SAVEPOINT

Usuwa punkt zapisu. Po tym już nie możesz się do niego cofnąć.

RELEASE SAVEPOINT mypoint;

Przykład: dodawanie danych do kilku tabel z możliwością cofnięcia

Załóżmy, że robisz system zarządzania zamówieniami, gdzie trzeba zapisać dane naraz do dwóch tabel: orders i order_items. Błąd przy dodawaniu do jednej tabeli nie powinien powodować cofnięcia danych z drugiej.

BEGIN; -- Start transakcji

-- Tworzymy punkt zapisu
SAVEPOINT before_order;

-- Dodajemy zamówienie do tabeli orders
INSERT INTO orders (order_id, customer_id, date)
VALUES (1, 101, CURRENT_DATE);

-- Jeśli tu pojawi się błąd — cofamy się
SAVEPOINT before_order_items;

-- Dodajemy produkty do tabeli order_items
INSERT INTO order_items (order_id, product_id, quantity)
VALUES (1, 2001, 4);

-- Jak coś pójdzie nie tak
-- ROLLBACK TO SAVEPOINT before_order_items;

-- Zatwierdzamy transakcję (commitujemy zmiany)
COMMIT;

Jeśli na etapie dodawania rekordów do order_items pojawi się błąd, możesz się cofnąć do punktu before_order_items, a zmiany w tabeli orders zostaną zachowane.

Praktyczne tipy i typowe wtopy

Teraz, kiedy już ogarniasz jak działają komendy SAVEPOINT i ROLLBACK TO SAVEPOINT, parę rad, żeby nie wpaść w kłopoty:

  1. Nazwy punktów zapisu. Używaj czytelnych i unikalnych nazw dla SAVEPOINT. Na przykład before_insert, step1 i tak dalej — to mega pomaga przy debugowaniu.
  2. Nie zapominaj zwalniać SAVEPOINT. Jeśli już nie planujesz wracać do punktu, usuwaj go przez RELEASE SAVEPOINT, żeby nie zaśmiecać transakcji.
  3. Zagnieżdżona transakcja ≠ osobna transakcja. Pamiętaj, że po komendzie COMMIT wszystkie punkty zapisu znikają. Jak zrobisz zewnętrzny COMMIT, już nie ma odwrotu.
  4. Blokowanie danych. Nawet jeśli cofniesz się do punktu, blokady rekordów ustawione w ramach transakcji zostają. To ważne, szczególnie jak pracujesz w środowisku z wieloma userami.

Zagnieżdżone transakcje z użyciem SAVEPOINT i ROLLBACK TO SAVEPOINT dają programistom mocne narzędzie do ogarniania trudnych sytuacji. Teraz możesz dzielić transakcje na elastyczne etapy, sprytnie obsługiwać błędy i unikać niepotrzebnego cofania danych. Pamiętaj, że jak widzisz słowo "cofnij", to nie zawsze powód do paniki: czasem cofnięcie to najlepszy sposób, żeby ruszyć dalej.

Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION