Si j'effectue un seul appel vers une base de données SQL Server sur un réseau à latence élevée, des verrous de table se produiront-ils en raison de cette latence? Supposons que j'interroge la table A pour certains enregistrements, et SQL Server doit renvoyer ces données sur un réseau lent - y aura-t-il un verrou de lecture sur la table A pendant que le serveur envoie la réponse sur le réseau, ou SQL Server libère-t-il le verrou avant d'envoyer la réponse?
De plus, la réponse varierait-elle en fonction de la taille de la réponse? S'il suffit de renvoyer quelques Ko contre plusieurs centaines de Mo, cela ferait-il une différence?
La création d'une transaction explicite, l'exécution de requêtes et la fermeture de la transaction entraîneraient évidemment le verrouillage des tables, car la durée de la transaction est corrélée avec ma latence.
la source
nolock
indice, il y aura toujours un verrou . La latence détermine simplement la durée du verrouillage.nolock
, vous obtiendrez toujours des verrousUnless you specify a nolock hint, there will always be a lock.
<- cela implique que si vous utilisez nolock, il pourrait ne pas y avoir de verrous. Je clarifiais simplement.Réponses:
Ce n'est pas précis, cela dépend du niveau d'isolement.
Par défaut, les
READ COMMITTED
verrous ne sont pas maintenus pendant la durée de l'exécution des instructions.READ COMMITTED
ne fournit pas de cohérence de lecture au niveau de l'instruction, la seule garantie est que vous ne pouvez pas lire les données non validées. Un verrou partagé est acquis et maintenu pour lire la ligne, puis libéré.Sauf si vous avez des types de LOB.
Les types de LOB, étant potentiellement très volumineux, ne peuvent pas être mis en mémoire tampon. Un verrou partagé doit être acquis et maintenu jusqu'à la fin de l'instruction, ce qui vous donne essentiellement un
REPEATABLE READ
comportement àREAD COMMITTED
.La latence ne provoque pas le verrouillage de la table, non. Cependant, si un verrou de table a été acquis, la latence va le prolonger.
Pour citer quelqu'un qui connaît mieux la mécanique que moi ( @RemusRusanu ):
Lorsque les résultats ne sont pas consommés aussi rapidement que SQL Server peut les fournir, que ce soit à cause du client ou du réseau, nous voyons des
ASYNC_NETWORK_IO
attentes s'accumuler. Pour le répéter, cela n'influencera pas les verrous acquis, mais uniquement la durée de leur maintien.la source
La réponse de Mark a dissipé une grande partie de ma confusion, mais je voulais publier mes résultats après avoir testé cela en utilisant NetBalancer pour émuler la latence.
J'ai demandé à ma machine locale d'appeler un serveur SQL distant et d'exécuter les sélections et les insertions sur une table au sein d'une petite transaction. Sur la machine distante, je me suis connecté à l'instance SQL locale et j'ai utilisé une boucle WHILE pour répéter de manière répétée la table sys.dm_tran_locks, à la recherche de verrous sur la table que je modifiais et lisais. J'ai installé NetBalancer sur le serveur et l'ai utilisé pour émuler la latence du réseau sur la connexion réseau du serveur.
Voici ce que j'ai trouvé:
De cela, je conclus que la latence n'a pas d'importance tant que les données tiennent dans la mémoire tampon du réseau. Si SQL doit mettre beaucoup de données dans le tampon réseau, la latence entraînera la sauvegarde de ce tampon et SQL maintiendra les verrous de table jusqu'à ce qu'il puisse placer tous les résultats de la requête dans le tampon.
la source
Lorsqu'une requête est déclenchée et terminée par SQL Server, elle produit les résultats, la place dans le tampon de sortie et l'envoie au client qui récupère ensuite le résultat dans le tampon de sortie. SQL Server ne libérera pas les verrous détenus par la requête à moins que l'accusé de réception ne soit reçu du client. Ce qui pourrait provoquer un blocage.
Edit: Evan vous pouvez vous référer à cet article de support MS
Dans la section 3
Blocage provoqué par un SPID dont l'application cliente correspondante n'a pas récupéré toutes les lignes de résultats jusqu'à la fin
Après avoir envoyé une requête au serveur, toutes les applications doivent immédiatement récupérer toutes les lignes de résultat jusqu'à leur achèvement. Si une application ne récupère pas toutes les lignes de résultats, des verrous peuvent être laissés sur les tables, bloquant les autres utilisateurs. Si vous utilisez une application qui soumet de manière transparente des instructions SQL au serveur, l'application doit récupérer toutes les lignes de résultat. Si ce n'est pas le cas (et s'il ne peut pas être configuré pour le faire), vous ne pourrez peut-être pas résoudre le problème de blocage. Pour éviter le problème, vous pouvez restreindre les applications mal comportées à une base de données de génération de rapports ou d'aide à la décision.
la source
SELECT *
à partir de celui-ci dansREAD COMMITTED
une connexion SSMS, le moniteur se verrouille d'une autre. À tout moment, combien de verrous voyez-vous?