Una semplice query di selezione acquisisce i blocchi?


14

Sono molto nuovo di SQL Server e vorrei capire se la seguente, semplicissima selectistruzione richiederebbe qualche blocco.

Select * from Student;

Si prega di considerare il caso in cui l'istruzione non sarebbe in esecuzione all'interno di un begin tranblocco.


1
Questa è una domanda molto più complicata di quanto si possa pensare. La risposta dipende da molte cose (qual è il livello di isolamento della transazione di sessione? Viene attivato l'isolamento dello snapshot di commit della lettura attivato? L'indice scansionato ha opzioni impostate per impedire il blocco di riga o di pagina?) E può persino cambiare durante l'esecuzione dell'istruzione (quante le righe sono nella tabella? la tabella è partizionata?). Ecco un buon punto per iniziare a leggere.
Jon Seigel,

Risposte:


5

Sì, richiede un blocco condiviso sulle righe che legge per impostazione predefinita (richiede anche un blocco Intent Shared su tutte le pagine dell'indice cluster che leggerà), questo per evitare letture errate. Tuttavia ci sono modi per aggirare questo (SQL Server ha il suggerimento nolock). Se l'istruzione non si trova in BEGIN TRAN, il blocco viene rilasciato dopo l'esecuzione dell'istruzione SELECT.

Maggiori informazioni possono essere trovate qui:

http://msdn.microsoft.com/en-us/library/ms184286(v=sql.105).aspx http://www.sqlteam.com/article/introduction-to-locking-in-sql-server


Inoltre, puoi anche impostare il livello di isolamento della transazione in modo che sia letto senza commit.
Zane,

1
Quindi, se SELECT legge dieci righe, i dieci blocchi condivisi vengono mantenuti fino a quando tutte e dieci le righe non sono state lette o vengono acquisite e rilasciate per riga?
Ian Warburton

26

Vorrei capire se la seguente istruzione select molto semplice richiederebbe qualsiasi blocco

È un'idea sbagliata comune che una SELECTquery in esecuzione al READ COMMITTEDlivello di isolamento della transazione predefinito prenderà sempre blocchi condivisi per impedire letture errate .

SQL Server può evitare di eseguire blocchi condivisi a livello di riga quando non vi è alcun pericolo di leggere dati senza commit senza di essi (sebbene vengano ancora adottati blocchi Intent-Shared (IS) di livello superiore).

Anche se blocchi di riga condivisi vengono prese (forse perché un'altra transazione concorrente ha modificato la pagina di fila è acceso) possono essere rilasciati molto prima che le SELECTcompleta l'istruzione.

Nella maggior parte dei casi, la riga viene "sbloccata" appena prima che il server elabori la riga successiva. Vi sono circostanze in cui i blocchi condivisi presi al livello di isolamento predefinito vengono mantenuti alla fine dell'istruzione corrente, ma non alla fine della transazione .

Sostituire l'attuale livello di isolamento con il NOLOCKsuggerimento della tabella è quasi sempre una cattiva idea .

Il blocco è un dettaglio di implementazione. Se necessario, SQL Server esegue i blocchi per garantire che soddisfi le garanzie semantiche fornite dall'attuale livello di isolamento . Ci sono certamente momenti in cui è utile sapere un po 'perché vengono prese le serrature, ma il tentativo di prevederle è spesso controproducente.

SQL Server offre un'ampia varietà di livelli di isolamento; scegli quello che fornisce le garanzie e i comportamenti di cui i consumatori hanno bisogno.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.