FOR UPDATE SKIP LOCKED și NOWAIT (Blocare fără Așteptare) în MySQL

Citirea datelor MySQL 8.0+

Implementarea cozilor de mesaje paralele de înaltă frecvență în MySQL: blocarea rândurilor libere și ignorarea automată a rândurilor blocate de alte tranzacții.

Sintaxă
SELECT * FROM coada_joburi WHERE status = 'nou' LIMIT 1 FOR UPDATE SKIP LOCKED;

Înainte de MySQL 8.0, utilizarea MySQL pe post de coadă de sarcini asincrone (Message Queue / Job Queue) era problematică: când mai mulți lucrători (workers) rulau concurent SELECT ... FOR UPDATE pentru a prelua o sarcină, aceștia se blocau unii pe alții, așteptând ca prima tranzacție să finalizeze blocajul (Lock Wait Timeout).

MySQL 8.0 a introdus clauzele SKIP LOCKED și NOWAIT, transformând baza de date într-un motor de cozi de înaltă concurență capabil să deservească mii de procese paralele fără timpi morți de așteptare.

1. SKIP LOCKED: Procesare concurentă fără blocaje de coadă
-- Worker 1 și Worker 2 rulează această interogare exact în aceeași milisecundă:
START TRANSACTION;

-- SKIP LOCKED sare automat peste rândurile deja blocate de Worker 1
-- și îl returnează pe următorul rând liber disponibil instantaneu!
SELECT id, tip_task, payload 
FROM coada_notificari 
WHERE status = 'in_asteptare' 
LIMIT 1 
FOR UPDATE SKIP LOCKED;

-- Procesăm sarcina și actualizăm statusul
UPDATE coada_notificari SET status = 'procesat' WHERE id = 42;

COMMIT;
2. NOWAIT: Eșec instant dacă resursa este ocupată
-- Dacă un rând este deja blocat de altă tranzacție,
-- NOWAIT nu așteaptă nici măcar o milisecundă, ci returnează eroare imediată:
START TRANSACTION;

SELECT * FROM camere_hotel 
WHERE id = 101 
FOR UPDATE NOWAIT;
-- Dacă e blocat, returnează imediat: 
-- ERROR 3572 (HY000): Statement aborted because lock(s) could not be acquired immediately and NOWAIT is set.

Comparație între Modurile de Blocare

Clauză Comportament când rândul este blocat Caz optim de utilizare
FOR UPDATE (clasic) Așteaptă până la innodb_lock_wait_timeout (implicit 50 secunde) ca rândul să se elibereze. Transferuri bancare, actualizări critice de sold unde așteptarea este obligatorie.
FOR UPDATE NOWAIT Returnează eroare instantanee dacă rândul este ocupat. Rezervări de locuri la cinema/evenimente unde utilizatorul trebuie informat imediat că biletul e selectat.
FOR UPDATE SKIP LOCKED Ignoră silențios rândurile ocupate și returnează următorul rând liber. Sisteme de cozi (Queues), procesare comenzi distribuite pe mai mulți workeri.