Quelqu'un peut-il expliquer les implications de l'utilisation with (nolock)
sur les requêtes, quand vous devriez / ne devriez pas l'utiliser?
Par exemple, si vous avez une application bancaire avec des taux de transaction élevés et beaucoup de données dans certaines tables, dans quels types de requêtes nolock serait-il correct? Y a-t-il des cas où vous devriez toujours l'utiliser / ne jamais l'utiliser?
sql-server
nolock
Andy White
la source
la source
Réponses:
WITH (NOLOCK) équivaut à utiliser READ UNCOMMITED comme niveau d'isolement des transactions. Vous risquez donc de lire une ligne non validée qui est ensuite annulée, c'est-à-dire des données qui ne sont jamais entrées dans la base de données. Ainsi, bien qu'il puisse empêcher le blocage des lectures par d'autres opérations, il présente un risque. Dans une application bancaire avec des taux de transaction élevés, ce ne sera probablement pas la bonne solution à tout problème que vous essayez de résoudre à mon humble avis.
la source
NOLOCK
avec un,SELECT
vous courez le risque de renvoyer les mêmes lignes plus d'une fois (données dupliquées) si des données sont jamais insérées (ou mises à jour) dans la table lors d'une sélection.La question est de savoir ce qui est pire:
Pour les bases de données financières, les blocages sont bien pires que les valeurs erronées. Je sais que ça sonne à l'envers, mais écoutez-moi. L'exemple traditionnel des transactions de base de données consiste à mettre à jour deux lignes en soustrayant l'une et en ajoutant à une autre. C'est faux.
Dans une base de données financières, vous utilisez des transactions commerciales. Cela signifie ajouter une ligne à chaque compte. Il est de la plus haute importance que ces transactions se terminent et que les lignes soient correctement écrites.
Obtenir le solde du compte temporairement incorrect n'est pas un gros problème, c'est à cela que sert le rapprochement de fin de journée. Et un découvert d'un compte est beaucoup plus susceptible de se produire parce que deux distributeurs automatiques de billets sont utilisés à la fois qu'en raison d'une lecture non validée d'une base de données.
Cela dit, SQL Server 2005 a corrigé la plupart des bogues qui ont rendu
NOLOCK
nécessaire. Donc, à moins que vous n'utilisiez SQL Server 2000 ou une version antérieure, vous ne devriez pas en avoir besoin.Lectures complémentaires au
niveau des lignes
la source
Malheureusement, il ne s'agit pas seulement de lire des données non validées. En arrière-plan, vous pouvez finir par lire des pages deux fois (dans le cas d'un fractionnement de page), ou vous risquez de manquer complètement les pages. Vos résultats peuvent donc être très biaisés.
Consultez l'article d' Itzik Ben-Gan . Voici un extrait:
la source
L'exemple de manuel pour l'utilisation légitime de l'indice nolock est l'échantillonnage de rapports par rapport à une base de données OLTP à haute mise à jour.
Pour prendre un exemple d'actualité. Si une grande banque américaine a voulu générer un rapport horaire à la recherche des premiers signes d'une exécution au niveau de la ville sur la banque, une requête nolock pourrait parcourir les tableaux de transactions résumant les dépôts en espèces et les retraits en espèces par ville. Pour un tel rapport, le minuscule pourcentage d'erreur causé par les transactions de mise à jour annulées ne réduirait pas la valeur du rapport.
la source
Vous ne savez pas pourquoi vous n'encapsulez pas les transactions financières dans les transactions de la base de données (comme lorsque vous transférez des fonds d'un compte à un autre - vous ne validez pas un côté de la transaction à la fois - c'est pourquoi des transactions explicites existent). Même si votre code est braindead pour les transactions commerciales comme il semble, toutes les bases de données transactionnelles ont le potentiel de faire des annulations implicites en cas d'erreurs ou d'échecs. Je pense que cette discussion est bien au-dessus de votre tête.
Si vous rencontrez des problèmes de verrouillage, implémentez la gestion des versions et nettoyez votre code.
Aucun verrou ne renvoie non seulement des valeurs erronées, mais également des enregistrements fantômes et des doublons.
Il est faux de croire que cela accélère toujours l'exécution des requêtes. S'il n'y a pas de verrous en écriture sur une table, cela ne fait aucune différence. S'il y a des verrous sur la table, cela peut rendre la requête plus rapide, mais il y a une raison pour laquelle les verrous ont été inventés en premier lieu.
En toute justice, voici deux scénarios spéciaux où un indice nolock peut fournir une utilité
1) Base de données du serveur SQL antérieure à 2005 qui doit exécuter une longue requête sur la base de données OLTP en direct, cela peut être le seul moyen
2) Une application mal écrite qui verrouille les enregistrements et renvoie le contrôle à l'interface utilisateur et les lecteurs sont bloqués indéfiniment. Nolock peut être utile ici si l'application ne peut pas être corrigée (tierce partie, etc.) et que la base de données est antérieure à 2005 ou que le contrôle de version ne peut pas être activé.
la source
NOLOCK
est équivalent àREAD UNCOMMITTED
, cependant Microsoft dit que vous ne devez pas l'utiliser pour les instructionsUPDATE
orDELETE
:http://msdn.microsoft.com/en-us/library/ms187373.aspx
Cet article s'applique à SQL Server 2005, donc la prise en charge
NOLOCK
existe si vous utilisez cette version. Afin de pérenniser votre code (en supposant que vous avez décidé d'utiliser des lectures sales), vous pouvez l'utiliser dans vos procédures stockées:SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
la source
Vous pouvez l'utiliser lorsque vous ne lisez que des données, et vous ne vous souciez pas vraiment de savoir si vous récupérez des données qui ne sont pas encore validées.
Cela peut être plus rapide lors d'une opération de lecture, mais je ne peux pas vraiment dire de combien.
En général, je déconseille de l'utiliser - la lecture de données non validées peut être un peu déroutante au mieux.
la source
Un autre cas où cela est généralement correct est dans une base de données de rapports, où les données sont peut-être déjà vieillies et les écritures ne se produisent tout simplement pas. Dans ce cas, cependant, l'option doit être définie au niveau de la base de données ou de la table par l'administrateur en modifiant le niveau d'isolement par défaut.
Dans le cas général: vous pouvez l' utiliser lorsque vous êtes très sûr qu'il est correct de lire les anciennes données. La chose importante à retenir est qu'il est très facile de se tromper . Par exemple, même si tout va bien au moment où vous écrivez la requête, êtes-vous sûr que quelque chose ne changera pas dans la base de données à l'avenir pour rendre ces mises à jour plus importantes?
Je vais également 2ème l'idée que ce n'est probablement pas une bonne idée dans l'application bancaire. Ou une application d'inventaire. Ou partout où vous pensez aux transactions.
la source
Réponse simple - chaque fois que votre SQL ne modifie pas les données et que vous avez une requête qui pourrait interférer avec d'autres activités (via le verrouillage).
Cela vaut la peine d'être pris en compte pour toutes les requêtes utilisées pour les rapports, surtout si la requête prend plus de, disons, 1 seconde.
C'est particulièrement utile si vous avez des rapports de type OLAP que vous exécutez sur une base de données OLTP.
La première question à se poser, cependant, est "pourquoi suis-je inquiet à ce sujet?" D'après mon expérience, le trucage du comportement de verrouillage par défaut se produit souvent lorsque quelqu'un est en mode "essayer quelque chose" et c'est un cas où des conséquences inattendues ne sont pas improbables. Trop souvent, il s'agit d'une optimisation prématurée et peut trop facilement être intégré dans une application "au cas où". Il est important de comprendre pourquoi vous le faites, quel problème il résout et si vous avez réellement le problème.
la source
Réponse courte:
Utilisez uniquement
WITH (NOLOCK)
dans l'instruction SELECT sur les tables qui ont un index cluster.Longue réponse:
WITH (NOLOCK) est souvent exploité comme un moyen magique pour accélérer les lectures de bases de données.
Le jeu de résultats peut contenir des lignes qui n'ont pas encore été validées, qui sont souvent annulées ultérieurement.
Si WITH (NOLOCK) est appliqué à une table qui a un index non clusterisé, les index de ligne peuvent être modifiés par d'autres transactions lorsque les données de ligne sont diffusées dans la table de résultats. Cela signifie que l'ensemble de résultats peut manquer de lignes ou afficher plusieurs fois la même ligne.
READ COMMITTED ajoute un problème supplémentaire où les données sont corrompues dans une seule colonne où plusieurs utilisateurs changent la même cellule simultanément.
la source
READ UNCOMITTED
ne l'affectera pas du tout. Il y a une raison pour laquelle il a été inclus dans la norme ANSI.Mes 2 cents - il est logique d'utiliser
WITH (NOLOCK
) lorsque vous devez générer des rapports. À ce stade, les données ne changeraient pas beaucoup et vous ne voudriez pas verrouiller ces enregistrements.la source
Si vous gérez des transactions financières, vous ne voudrez plus jamais les utiliser
nolock
.nolock
est mieux utilisé pour sélectionner parmi de grandes tables qui ont beaucoup de mises à jour et vous ne vous souciez pas si l'enregistrement que vous obtenez pourrait être obsolète.Pour les enregistrements financiers (et presque tous les autres enregistrements dans la plupart des applications), cela
nolock
ferait des ravages car vous pourriez potentiellement lire les données d'un enregistrement en cours d'écriture et ne pas obtenir les données correctes.la source
J'ai utilisé pour récupérer un "prochain lot" pour les choses à faire. Peu importe dans ce cas quel élément exact, et j'ai beaucoup d'utilisateurs exécutant cette même requête.
la source
Utilisez nolock lorsque vous êtes d'accord avec les données "sales". Ce qui signifie que nolock peut également lire des données en cours de modification et / ou non validées.
Ce n'est généralement pas une bonne idée de l'utiliser dans un environnement de transactions élevées et c'est pourquoi ce n'est pas une option par défaut sur la requête.
la source
J'utilise avec (nolock) hint en particulier dans les bases de données SQLServer 2000 à forte activité. Je ne suis pas certain cependant qu'il soit nécessaire dans SQL Server 2005. J'ai récemment ajouté cet indice dans un SQL Server 2000 à la demande du DBA du client, car il remarquait de nombreux verrous d'enregistrement SPID.
Tout ce que je peux dire, c'est que l'utilisation de l'indice ne nous a PAS fait de mal et semble avoir résolu le problème de verrouillage. Le DBA de ce client particulier a essentiellement insisté pour que nous utilisions l'indice.
Soit dit en passant, les bases de données avec lesquelles je traite sont des back-ends pour les systèmes de réclamations médicales d'entreprise, nous parlons donc de millions d'enregistrements et de plus de 20 tables dans de nombreuses jointures. J'ajoute généralement un indice WITH (nolock) pour chaque table de la jointure (sauf s'il s'agit d'une table dérivée, auquel cas vous ne pouvez pas utiliser cet indice particulier)
la source
La réponse la plus simple est une question simple - avez-vous besoin que vos résultats soient reproductibles? Si oui, NOLOCKS ne convient en aucun cas
Si vous n'avez pas besoin de répétabilité, les nolocks peuvent être utiles, surtout si vous n'avez pas le contrôle sur tous les processus se connectant à la base de données cible.
la source