Con l'emergere di database multiutente è sorta la necessità di limitare la modifica simultanea degli stessi dati. Questo ha portato all'emergere di vari meccanismi di locking (gestione dei locking), che prevenire le modifiche parallele e aiutano a mantenere l'integrità dei dati.
Senza un controllo dell'accesso, le operazioni simultanee possono portare a danneggiamento o perdita di dati: ad esempio, due transazioni aggiornano simultaneamente una riga e le modifiche di una transazione vengono perse. Locking non sufficientemente rigorosi portano a problemi di concorrenza (race conditions), mentre un eccesso porta a perdite di prestazioni (deadlocks, contention).
Nei moderni DBMS ci sono livelli di locking (row-level, page-level, table-level) e diverse modalità (shared, exclusive, update). Il programmatore può gestirli attraverso impostazioni di isolamento delle transazioni e comandi espliciti di locking (ad esempio, SELECT ... FOR UPDATE).
Esempio di codice:
-- Locking della riga fino al completamento della transazione BEGIN TRANSACTION; SELECT * FROM users WHERE id = 1 FOR UPDATE; UPDATE users SET name = 'New Name' WHERE id = 1; COMMIT;
Caratteristiche chiave:
Qual è la differenza tra un locking di lettura (shared lock) e di scrittura (exclusive lock)?
Lo shared lock consente a più transazioni di leggere i dati simultaneamente, ma non di modificarli. L'exclusive lock consente solo a una transazione di modificare i dati, mentre a tutte le altre è vietato l'accesso.
Può un comando SELECT causare un locking?
Di solito SELECT non causa locking, ma se si usa SELECT ... FOR UPDATE o in caso di alto livello di isolamento (ad esempio, SERIALIZABLE), il DBMS può bloccare le righe.
Esempio di codice:
SELECT * FROM products WHERE id = 10 FOR UPDATE;
I locking proteggono sempre dalla "perdita di aggiornamenti"?
No, se il livello di locking o di isolamento è scelto in modo errato, si può ottenere una "lost update" — quando le modifiche di una transazione vengono perse a causa di un'altra. È necessario scegliere con attenzione i meccanismi di gestione della concorrenza.
Nel dipartimento di analisi, due programmi aggiornano simultaneamente gli stati degli ordini. Per accelerare, è stato impostato il livello READ UNCOMMITTED per non bloccare le righe. Questo ha portato a conflitti e "perdita" di aggiornamenti, parte dei dati è stata danneggiata.
Pro:
Contro:
Nel dipartimento vendite, i punti critici sono stati protetti con TRANSACTION + SELECT ... FOR UPDATE. È stata separata l'operazione di lettura da quella di aggiornamento a livello di riga.
Pro:
Contro: