Supposons que j'ai la requête longue durée suivante
UPDATE [Table1]
SET [Col1] = 'some value'
WHERE [Col2] -- some clause which selects thousands of rows
et supposons que la requête suivante est exécutée pendant l'exécution de la requête ci-dessus
SELECT *
FROM [Table1]
La première requête empêche-t-elle l'exécution de la deuxième requête jusqu'à ce que la première requête soit terminée? Dans l'affirmative, la première requête empêche-t-elle la deuxième requête de s'exécuter sur toutes les lignes ou uniquement sur les lignes impliquées dans la clause WHERE?
ÉDITER:
Supposons que la deuxième requête soit
SELECT [Col1], [Col2]
FROM [Table1]
WHERE [Col2] -- some clause whose matching elements overlap those from
-- the clause in the first query and which has additional matching elements
la source
SELECT * FROM Table1
si c'est exactement ce dont j'ai besoin?*
en soi est une mauvaise pratique car lorsque la structure de la table change, l'application se casse généralement (des colonnes inattendues apparaissent dans le résultat).Edit: Comme le souligne @MaxVernon , ce qui suit n'est en aucun cas une suggestion d'utiliser NOLOCK , et j'aurais très bien dû mentionner la définition du niveau de transaction
READ UNCOMMITED
et laisser la connotation négative se tenir là plutôt que d'évoquerNOLOCK
en premier lieu. Donc, comme initialement affiché:La réponse rapide et simple est "Oui, la première requête bloquera la deuxième requête, sauf si un indice d'index spécifique est spécifié ( NOLOCK , parfois appelé" lecture incorrecte ") ou si le niveau d'isolement des transactions de la deuxième requête est défini sur
READ UNCOMMITED
(qui fonctionne de manière identique), non."En réponse aux détails supplémentaires fournis dans la question entraînant l'inclusion d'une
WITH
clause sur la secondeSELECT
, s'excluant mutuellement ou non, les interactions entre les deux requêtes seront largement les mêmes.Dans une session distincte, exécutez ce qui suit:
Vous pouvez examiner les verrous actuellement détenus en exécutant
sp_lock
, de préférence dans une autre session distincte:Vous devriez voir un
KEY
verrou de type détenu par le spid effectuant la transaction d'insertion enX
mode (exclusif), à ne pas confondre avec les autresIX
verrous (Intent-Exclusive). La documentation du verrou indique que leKEY
verrouillage est spécifique à la plage, mais il empêche également d'autres transactions d'insérer ou de mettre à jour les colonnes affectées en modifiant les données qui y sont contenues afin qu'elles puissent entrer dans cette plage de la requête d'origine. Le verrou lui-même étant exclusif, la première requête empêche l'accès à la ressource de toute autre transaction simultanée. En effet, toutes les lignes de la colonne sont verrouillées, qu'elles appartiennent ou non à la plage spécifiée par la première requête.Le
S
verrou détenu par la deuxième session sera doncWAIT
jusqu'à ce que leX
verrou soit effacé, empêchant un autreX
(ouU
) verrou d'être pris sur cette ressource à partir d'un spid simultané différent avant que la deuxième session ne termine son opération de lecture, justifiant l'existence duS
verrou.Maintenant, une modification pour plus de clarté: à moins que je ne me trompe dans ce qu'est une lecture sale de la brève description des risques mentionnés ici ... Edit 3 : Je viens de réaliser que je ne considère pas l'effet d'un point de contrôle de fond qui écrit un comme de transaction encore non validée sur le disque, donc oui, mon explication était trompeuse.
Dans la deuxième requête, le premier lot peut (et dans ce cas, renverra) des données non validées. Le deuxième lot, exécuté au niveau d'isolation de transaction par défaut de,
READ COMMITED
ne sera renvoyé qu'après la fin d'une validation ou d'une restauration dans la première session.À partir d'ici, vous pouvez consulter vos plans de requête et les niveaux de verrouillage associés, mais mieux encore, vous pouvez lire tout sur les verrous dans SQL Server ici .
la source
WITH (NOLOCK)
serait utile dans ce cas. Voir brentozar.com/archive/2011/11/… et brentozar.com/archive/2013/02/… pour plus de lecture.WITH (NOLOCK)
indice ne renvoie pas les pages sales de la mémoire qui n'ont pas été validées. Il lit en fait les lignes de la table (qu'elles soient sur disque ou en mémoire cache) sans empêcher les écrivains de mettre à jour ou d'ajouter des lignes aux pages utilisées par la table.