MODUL 5 - LEKCIJA 1

Transakcije i Konkurentnost

Duboko razumijevanje izolacionih nivoa, zaključavanja (locking) i rješavanja deadlock-a

⏱️ Trajanje: ~4 časa 📚 Nivo: Napredni 🎯 Praktični primjeri: 7

📖 Temelj Integriteta: ACID

Svaki sistem koji radi sa novcem ili kritičnim podacima mora garantovati ACID svojstva:

⚖️ Nivoi Izolacije (Isolation Levels)

Što je veća izolacija, to je manje grešaka, ali je sistem sporiji zbog čekanja na zaključavanje.

Nivo Opis Problem koji rješava
READ UNCOMMITTED "Dirty Read". Najbrži, ali čita podatke koji se možda nikad ne spase. Ništa.
READ COMMITTED Default u SQL Serveru. Čita samo spašene podatke. Dirty Read.
SNAPSHOT Koristi verziranje redova (MVCC). Čitaoci ne blokiraju pisce. Blokiranje.
SERIALIZABLE Najveća izolacija. Transakcije idu jedna po jedna kao na traci. Phantoms (fantomski redovi).

🔐 Mehanizmi Zaključavanja (Locking)

SQL Server koristi različite tipove "katanaca" kako bi zaštitio podatke:

🔍 Provjera trenutnih zaključavanja
-- Pogledajte ko koga blokira u realnom vremenu
SELECT 
    session_id, 
    blocking_session_id, 
    wait_type, 
    wait_time_ms,
    resource_description
FROM sys.dm_os_waiting_tasks
WHERE blocking_session_id IS NOT NULL;

💀 Deadlock: Pat pozicija

Deadlock se dešava kada Transakcija A zaključa Red 1 i čeka na Red 2, dok Transakcija B drži Red 2 i čeka na Red 1. SQL Server automatski ubija jednu transakciju (Deadlock Victim) kako bi oslobodio sistem.

🛡️ Kako spriječiti Deadlock?

  • Pristupajte tabelama uvijek istim redoslijedom u svim procedurama.
  • Držite transakcije što kraćim (ne čekajte na korisnički unos unutar transakcije!).
  • Koristite Snapshot Isolation ako imate sistem sa puno čitanja.

🎯 Praktična Vježba: Simulacija Trke (Race Condition)

Zadatak: Update Stanja na Računu

Dva korisnika istovremeno pokušavaju podići novac. Morate osigurati da stanje nikada ne padne ispod nule, bez obzira na konkurentnost.

💡 Sigurno Rješenje
BEGIN TRANSACTION;
    -- Koristimo UPDLOCK da odmah zaključamo red za pisanje, čak i dok samo čitamo
    DECLARE @Balance DECIMAL(18,2);
    SELECT @Balance = Balance FROM Accounts WITH (UPDLOCK) WHERE AccountID = 101;

    IF @Balance >= 100
    BEGIN
        WAITFOR DELAY '00:00:05'; -- Simulacija procesiranja
        UPDATE Accounts SET Balance = Balance - 100 WHERE AccountID = 101;
        COMMIT;
    END
    ELSE
    BEGIN
        ROLLBACK;
        PRINT 'Nedovoljno sredstava.';
    END

✅ Zaključak

Vladanje konkurentnošću dijeli juniore od seniora:

📚 Sljedeća Lekcija

U Lekciji 5.2 prelazimo na Optimizaciju Performansi. Naučićete kako čitati Execution Plans i kako "nagovoriti" Query Optimizer da izabere najbrži put do vaših podataka.