Sql Server- Hint di tabella

Gli hint di tabella consentono di modificare il comportamento predefinito di Query Optimizer per la durata dell’istruzione DML (Data Manipulation Language) specificando un metodo di blocco, uno o più indici, un’operazione di elaborazione di query, quale un’analisi di tabella (Table Scan) o una ricerca nell’indice (Index Seek), oppure altre opzioni [1].

La sintassi è la seguente:

WITH ( <table_hint> ) [ [, ]...n ]

NOLOCK (READUNCOMMITTED)

Questo comando permette di evitare il blocco dei dati dovuti ad una transazione non chiusa.

Spieghiamo il funzionamento di questo comando con un esempio:
La query seguente ritorna tutti i record della tabella Contact

SELECT * FROM Person.Contact

Ora assumiamo che vi sia un secondo utente che lancia la query sopra in una transazione (senza chiuderla). La query viene completata e i record aggiornati, ma non essendo stata committata i record su DB sono LOCKED.

SELECT * FROM Person.Contact
BEGIN TRAN
UPDATE Person.Contact SET Suffix = 'B'
-- ROLLBACK or COMMIT

Conseguentemente se io lancio ancora la query di UPDATE indicata sopra, questa non terminerà mai, in quanto l’UPDATE non è stato committato.
Per verificare questo posso usare la stored procedure sp_who2

EXEC sp_who2

Che fornisce una serie di informazioni sui processi in atto sul server, in questo caso mi permette di vedere che l’istruzione SELECT è stata bloccata (AWAITING COMMAND).

Devo o cancellare l’esecuzione della query o eseguire un COMMIT o ROLLBACK dell’istruzione appena eseguita.

Per evitare il problema dei record bloccati prima di un commit posso usare unWITH (NOLOCK) che completerà la query anche se i record in questione sono bloccati in quanto un’altra transazione è in esecuzione.

SELECT * FROM Person.Contact WITH (NOLOCK)

Questa operazione esegue una lettura sporca (Dirty read) in quanto sto leggendo dei dati che non so se esistono veramente (all’update seguirà un commit) o no (all’update seguirà un rollback).
Quindi se sto banalmente mostrando dei record posso usare il NOLOCK senza preoccupazioni, se però devo lavorare con dei dati consistenti allora questa soluzione mi espone al rischio di lavorare con dei dati falsi.
Il comando NOLOCK è un sinonimo di READUNCOMMITED e possono essere usati equivalentamentemente.

SELECT * FROM Person.Contact WITH (READUNCOMMITTED)

E’ da sottolineare il fatto che questi comandi sono compatibili solo con un istruzione di SELECT.

Effetti del NOLOCK

  • Lettura sporca: come indicato sopra, posso leggere dati che non esistono
  • Righe mancanti: altre transazioni possono muovere che non hai ancora letto in un posto in cui hai invece appena letto, perdendo conseguentemente tali dati
  • Righe duplicate: simmetricamente a quanto indicato sopra, posso leggere due volte la stessa riga
  • Leggere versioni multiple della stessa riga
  • Errori in lettura: dato che posso poter leggere dei dati che sono stati spostati durante la lettura, potrei incorrere in questo errore: Could not continue scan with NOLOCK due to data movement.

Per approfondire consiglio i seguenti articoli:

Indice

Share
Ultimi articoli
Join

Newsletter

Nessuno spam, solo articoli interessanti ;)

Focus

Post correlati

sharding

Cosa è il database sharding?

Introduzione Ogni applicazione che utilizza un database deve pensare a come gestire un aumento delle richieste e dell’utilizzo di questa ultima senza comprometterne l’usabilità. Rendere

WITH – Common Table Expression

Le Common Table Expression forniscono una sintassi alternativa per evitare l’accumularsi di query innestate: permettono di creare delle tabelle temporanee basandosi sui risultati di una

Utilizzare la clausola ROLLUP

Talvolta voglio eseguire una query che mi fornisca dei risultati aggregati di media, min, max… ma anche dei risultati sull’intero rowset senza aggregazione. Per avere

Codice Pragmatico

Contatti

Per informazioni, dubbi o consulenze non esitate a contattarmi.

Lascia un messaggio

Ricevi le ultime news

Iscrivi alla newsletter

Solo articoli interessanti, promesso ;)