0Pricing
Java Academy · Lekcja

Transakcje

Commit i rollback

Transakcje to bezpłatna lekcja Java Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Java Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Java Academy zawiera 4 lekcji w sumie.

Czym jest transakcja

Transakcja grupuje kilka operacji SQL w jedną jednostkę wykonywaną w całości albo wcale.

Albo każda instrukcja kończy się powodzeniem i zmiany zostają trwale zapisane (commit), albo coś się nie powiedzie i wszystkie zmiany zostaną wycofane (rollback). Dzięki temu baza danych zachowuje spójność.

ACID w minutę

Transakcje zapewniają gwarancje ACID:

  • Atomowość — wszystko albo nic.
  • Spójność — przenosi bazę danych z jednego prawidłowego stanu do innego.
  • Izolacja — równoczesne transakcje nie powodują wzajemnego uszkodzenia danych.
  • Trwałość — po zatwierdzeniu zmiany przetrwają awarię.

Tryb automatycznego zatwierdzania

Domyślnie połączenia JDBC działają w trybie auto-commit: każda instrukcja stanowi osobną transakcję i jest natychmiast zatwierdzana.

Sprawdza się to w przypadku pojedynczych instrukcji, ale nie działa, gdy kilka operacji zapisu musi zakończyć się powodzeniem jako całość. Aby samodzielnie sterować transakcjami, należy wyłączyć auto-commit.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class Main {
    public static void main(String[] args) {
        String url = "jdbc:postgresql://localhost:5432/bank";
        try (Connection conn = DriverManager.getConnection(url, "app", "secret")) {
            System.out.println("Default auto-commit: " + conn.getAutoCommit());
            conn.setAutoCommit(false);
            System.out.println("Now manual: " + conn.getAutoCommit());
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
    }
}

Commit i rollback

Przy wyłączonym auto-commit samodzielnie określa się granice transakcji:

  • conn.commit() trwale zapisuje wszystkie oczekujące zmiany.
  • conn.rollback() je odrzuca.

Klasycznym przykładem jest przelew pieniędzy: obciążenie jednego konta i uznanie drugiego. Obie operacje muszą się udać albo żadna z nich.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Main {
    public static void main(String[] args) {
        String url = "jdbc:postgresql://localhost:5432/bank";
        String debit = "UPDATE account SET balance = balance - ? WHERE id = ?";
        String credit = "UPDATE account SET balance = balance + ? WHERE id = ?";
        try (Connection conn = DriverManager.getConnection(url, "app", "secret")) {
            conn.setAutoCommit(false);
            try (PreparedStatement d = conn.prepareStatement(debit);
                 PreparedStatement c = conn.prepareStatement(credit)) {
                d.setInt(1, 100); d.setInt(2, 1); d.executeUpdate();
                c.setInt(1, 100); c.setInt(2, 2); c.executeUpdate();
                conn.commit();
                System.out.println("Transfer committed");
            } catch (SQLException ex) {
                conn.rollback();
                System.out.println("Rolled back: " + ex.getMessage());
            }
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
    }
}

Schemat wycofania w razie błędu

Struktura do zapamiętania:

  • Należy wyłączyć auto-commit.
  • Pracę należy wykonać wewnątrz wewnętrznego try.
  • Po pomyślnym zakończeniu należy wywołać commit().
  • W bloku catch należy wywołać rollback(), a następnie ponownie zgłosić błąd lub go zalogować.

Bez rollbacku awaria mogłaby pozostawić bazę danych częściowo zaktualizowaną.

Symulowanie atomowości

Oto idea wykonania wszystkiego albo niczego, przedstawiona w zwykłym kodzie Java, aby można było uruchomić go samodzielnie. Stosujemy dwie aktualizacje do migawki; jeśli którakolwiek się nie powiedzie, przywracamy migawkę.

public class Main {
    public static void main(String[] args) {
        int[] balances = {500, 300};
        int[] backup = balances.clone();
        try {
            balances[0] -= 200;
            if (balances[0] < 0) throw new IllegalStateException("insufficient funds");
            balances[1] += 200;
            System.out.println("Commit: " + balances[0] + ", " + balances[1]);
        } catch (RuntimeException e) {
            balances = backup;
            System.out.println("Rollback: " + balances[0] + ", " + balances[1]);
        }
    }
}

Punkty zapisu

Punkt zapisu to znacznik wewnątrz transakcji. Można wycofać zmiany do tego punktu bez odrzucania całej transakcji.

  • Savepoint sp = conn.setSavepoint()
  • conn.rollback(sp) wycofuje tylko zmiany wykonane po tym punkcie.

Jest to przydatne przy częściowym odzyskiwaniu danych w długich transakcjach.

Poziomy izolacji

Izolacja określa, co jedna transakcja widzi z niezatwierdzonych zmian drugiej. JDBC definiuje poziomy za pomocą conn.setTransactionIsolation(...):

  • TRANSACTION_READ_COMMITTED — często używany poziom domyślny.
  • TRANSACTION_REPEATABLE_READ
  • TRANSACTION_SERIALIZABLE — najsilniejszy, ale najwolniejszy.

Wyższy poziom izolacji zapobiega anomaliom, ale ogranicza współbieżność.

Anomalie odczytu

Niższe poziomy izolacji mogą umożliwiać:

  • Brudny odczyt — odczytanie niezatwierdzonej zmiany innej transakcji.
  • Odczyt niepowtarzalny — wiersz zmienia się między dwoma odczytami.
  • Odczyt fantomowy — pojawiają się nowe wiersze pasujące do wcześniejszego zapytania.

Należy wybrać najniższy poziom, który nadal zapobiega anomaliom niedopuszczalnym dla danej logiki.

Przywracanie auto-commit

Jeśli połączenie pobrano z puli, przed jego zwróceniem należy przywrócić jego pierwotny stan.

Po ręcznie zarządzanej transakcji należy ponownie ustawić conn.setAutoCommit(true) (lub przywrócić wartość odczytaną podczas pobierania), aby kolejny użytkownik nie został zaskoczony tymi ustawieniami.

Krótkie transakcje

Transakcja utrzymuje blokady do momentu zatwierdzenia lub wycofania. Długie transakcje blokują inne operacje i zwiększają ryzyko zakleszczeń.

  • Nie należy wykonywać wolnych wywołań sieciowych ani oczekiwać na działania użytkownika wewnątrz otwartej transakcji.
  • Najpierw należy zebrać dane, a następnie szybko otworzyć transakcję, wykonać zapis i ją zatwierdzić.

Krótkie transakcje o jasno określonym zakresie znacznie lepiej się skalują.

Szybkie sprawdzenie

Jaki jest skutek wywołania connection.rollback()?

Podsumowanie

Transakcje zapewniają bezpieczeństwo dzięki zasadzie „wszystko albo nic”:

  • Należy wyłączyć auto-commit za pomocą setAutoCommit(false).
  • Po powodzeniu wywołać commit(), a w razie błędu rollback().
  • Używać punktów zapisu do częściowego wycofywania zmian.
  • Dostosowywać poziomy izolacji, aby zachować równowagę między poprawnością a współbieżnością.
  • Przed zwróceniem połączenia do puli przywrócić auto-commit.

Często zadawane pytania

Czy lekcja „Transakcje” jest bezpłatna?

Tak — pełny tekst „Transakcje” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Java Academy, przejdź na CoddyKit PRO. Kurs Java Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Transakcje”?

Commit i rollback Ćwiczysz Java Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Java Academy?

Nie wymagamy żadnego doświadczenia. Java Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Transakcje”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Java Academy?

Tak. Każda lekcja Java Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Podstawy JDBC
  2. PreparedStatement
  3. Transakcje
  4. Pula połączeń z HikariCP
← Powrót do Java Academy