Ce face GET_LOCK()
GET_LOCK() creează o blocare identificată doar printr-un nume (maximum 64 de caractere). Cât timp o conexiune ține blocarea, celelalte care cer același nume așteaptă cel mult numărul de secunde dat, apoi primesc 0. O valoare negativă înseamnă așteptare fără limită.
Este o blocare „de bună înțelegere”: nu blochează tabele sau rânduri, ci doar alte apeluri GET_LOCK() cu același nume. Este folosită ca o aplicație să nu ruleze de două ori aceeași sarcină (de exemplu, un raport zilnic pornit din cron).
Blocarea se eliberează cu RELEASE_LOCK() sau automat când se închide conexiunea; COMMIT și ROLLBACK nu o eliberează. O conexiune poate lua aceeași blocare de mai multe ori și trebuie să o elibereze de tot atâtea ori.
Parametri
| Parametru | Descriere |
|---|---|
nume |
Numele blocării; folosește un prefix, de exemplu 'magazin.raport'. |
secunde_asteptare |
Cât se așteaptă; 0 = deloc, negativ = la nesfârșit. |
Ce returnează
1 dacă blocarea a fost obținută, 0 la expirarea timpului, NULL la eroare.
Exemple
Exemplul 1: Luarea și eliberarea unei blocări
SELECT GET_LOCK('magazin.raport_zilnic', 10) AS obtinuta;
SELECT IS_USED_LOCK('magazin.raport_zilnic') = CONNECTION_ID() AS o_tin_eu;
SELECT RELEASE_LOCK('magazin.raport_zilnic') AS eliberata;
Rezultat
+----------+
| obtinuta |
+----------+
| 1 |
+----------+
+----------+
| o_tin_eu |
+----------+
| 1 |
+----------+
+-----------+
| eliberata |
+-----------+
| 1 |
+-----------+
Exemplul 2: Două conexiuni cer aceeași blocare
-- conexiunea 1
SELECT GET_LOCK('magazin.raport_zilnic', 10);
-- conexiunea 2 (în același timp)
SELECT GET_LOCK('magazin.raport_zilnic', 3);
Rezultat în MySQL (două conexiuni deschise în paralel)
-- conexiunea 1
+---------------------------------------+
| GET_LOCK('magazin.raport_zilnic', 10) |
+---------------------------------------+
| 1 |
+---------------------------------------+
-- conexiunea 2: așteaptă 3 secunde, apoi renunță
+--------------------------------------+
| GET_LOCK('magazin.raport_zilnic', 3) |
+--------------------------------------+
| 0 |
+--------------------------------------+
1 row in set (3.00 sec)
Exemplul 3: Aceeași blocare luată de două ori
SELECT GET_LOCK('import', 0) AS prima, GET_LOCK('import', 0) AS a_doua;
SELECT RELEASE_LOCK('import') AS eliberare_1, IS_FREE_LOCK('import') AS libera_dupa_1;
SELECT RELEASE_LOCK('import') AS eliberare_2, IS_FREE_LOCK('import') AS libera_dupa_2;
Rezultat
+-------+--------+
| prima | a_doua |
+-------+--------+
| 1 | 1 |
+-------+--------+
+-------------+---------------+
| eliberare_1 | libera_dupa_1 |
+-------------+---------------+
| 1 | 0 |
+-------------+---------------+
+-------------+---------------+
| eliberare_2 | libera_dupa_2 |
+-------------+---------------+
| 1 | 1 |
+-------------+---------------+
Greșeli frecvente
- Crezi că
GET_LOCK()blochează un tabel. Alte conexiuni pot citi și modifica orice; sunt oprite doar cele care cer aceeași blocare. - Folosești nume generice ca
'lock'. Numele sunt comune pentru tot serverul, deci și alte aplicații le pot folosi; adaugă un prefix. - Uiți să eliberezi blocarea într-o conexiune care rămâne deschisă (pool de conexiuni). Blocarea rămâne luată până la închiderea conexiunii.
Comenzi înrudite
RELEASE_LOCK(): Eliberează o blocare luată cu GET_LOCK().IS_FREE_LOCK(): Verifică dacă o blocare cu nume este liberă (1) sau ținută de cineva (0).IS_USED_LOCK(): Returnează ID-ul conexiunii care ține o blocare cu nume, sau NULL dacă este liberă.START TRANSACTION / COMMIT / ROLLBACK: Grupează mai multe modificări: fie se aplică toate (COMMIT), fie niciuna (ROLLBACK).