Une simple requête de sélection acquiert-elle des verrous?

14

Je suis très nouveau sur SQL Server et j'aimerais comprendre si l' selectinstruction très simple suivante prendrait des verrous.

Select * from Student;

Veuillez considérer le cas où l'instruction ne s'exécuterait pas dans un begin tranbloc.

Nouveau développeur
la source
1
C'est une question beaucoup plus compliquée que vous ne le pensez. La réponse dépend de plusieurs éléments (quel est le niveau d'isolement des transactions de session? L'isolement des clichés validés en lecture est-il activé? L'index analysé a-t-il des options définies pour empêcher le verrouillage des lignes ou des pages?) Et peut même changer pendant l'exécution de l'instruction (combien lignes sont dans la table? la table est-elle partitionnée?). Voici un bon point pour commencer la lecture.
Jon Seigel

Réponses:

5

Oui, il prend un verrou partagé sur les lignes qu'il lit par défaut (il prend également un verrou partagé intentionnel sur toutes les pages de l'index cluster qu'il lira), cela est fait pour éviter les lectures sales. Cependant, il existe des moyens de contourner cela (SQL Server a l'indication nolock). Si l'instruction n'est pas dans un BEGIN TRAN, le verrou est libéré après l'exécution de l'instruction SELECT.

Plus d'informations peuvent être trouvées ici:

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

WrinkleFree
la source
De plus, vous pouvez également définir le niveau d'isolement des transactions pour lire non validé.
Zane
1
Donc, si le SELECT lit dix lignes, les dix verrous partagés sont-ils maintenus jusqu'à ce que les dix lignes aient été lues ou sont-elles acquises et libérées par ligne?
Ian Warburton
26

Je voudrais savoir si l'instruction de sélection suivante, très simple, prendrait des verrous

Il est faux de penser qu'une SELECTrequête exécutée au READ COMMITTEDniveau d'isolement de transaction par défaut prendra toujours des verrous partagés pour éviter les lectures incorrectes.

SQL Server peut éviter de prendre des verrous partagés au niveau des lignes lorsqu'il n'y a aucun danger de lire des données non validées sans eux (bien que des verrous d'intention partagés (IS) de niveau supérieur soient toujours pris).

Même si des verrous de ligne partagés sont pris (peut-être parce qu'une autre transaction simultanée a modifié la page sur laquelle la ligne se trouve), ils peuvent être libérés bien avant la fin de l' SELECTinstruction.

Dans la plupart des cas, la ligne est «déverrouillée» juste avant que le serveur ne traite la ligne suivante. Dans certains cas, les verrous partagés pris au niveau d'isolement par défaut sont conservés jusqu'à la fin de l'instruction en cours, mais pas jusqu'à la fin de la transaction .

Remplacer le niveau d'isolement actuel avec l' NOLOCKindicateur de table est presque toujours une mauvaise idée .

Le verrouillage est un détail d'implémentation. SQL Server prend des verrous lorsque cela est nécessaire pour garantir qu'il respecte les garanties sémantiques fournies par le niveau d'isolement actuel . Il y a certainement des moments où il est utile de savoir un peu pourquoi les verrous sont pris, mais tenter de les prévoir est très souvent contre-productif.

SQL Server fournit une grande variété de niveaux d'isolement; choisissez celui qui offre les garanties et les comportements dont vos clients ont besoin.

Paul White 9
la source