Question

Quelqu'un peut-il expliquer les implications de l'utilisation with (nolock) sur les requêtes, lorsque vous devriez / ne devrait pas l'utiliser?

Par exemple, si vous avez une application bancaire avec des taux élevés de transaction et un grand nombre de données dans certains tableaux, dans quels types de requêtes seraient nolock bien? Y at-il des cas où vous devriez toujours utiliser / jamais l'utiliser?

Était-ce utile?

La solution

(NOLOCK) est l'équivalent de l'utilisation LIRE UNCOMMITED comme un niveau d'isolement de la transaction. Donc, vous tenez le risque de lire une ligne non engagée qui est ensuite annulée, à savoir des données qui n'a jamais fait dans la base de données. Ainsi, alors qu'il peut éviter d'être dans l'impasse par les lectures d'autres opérations, il est livré avec un risque. Dans une application bancaire avec des taux élevés de transaction, il ne va probablement pas être la bonne solution à tout problème que vous essayez de résoudre avec elle à mon humble avis.

Autres conseils

La question est ce qui est pire:

  • une impasse, ou
  • une mauvaise valeur?

Pour les bases de données financières, sont bien pires blocages que des valeurs erronées. Je sais que cela semble en arrière, mais écoutez-moi. L'exemple traditionnel des transactions DB vous est mise à jour deux lignes, la soustraction d'un et en ajoutant à l'autre. Cela est faux.

Dans une base de données financières que vous utilisez les transactions commerciales. Cela signifie que l'ajout d'une ligne à chaque compte. Il est d'une importance capitale que ces transactions complètes et les lignes sont écrites avec succès.

Obtenir le solde du compte temporairement mauvais est pas une grosse affaire, c'est-ce que la fin de la réconciliation du jour est pour. Et un découvert bancaire d'un compte est beaucoup plus susceptible de se produire parce que deux distributeurs automatiques de billets sont utilisés à la fois que à cause d'une lecture non validée à partir d'une base de données.

Cela dit, SQL Server 2005 fixe la plupart des bugs qui ont fait NOLOCK nécessaire. Donc, sauf si vous utilisez SQL Server 2000 ou plus tôt, vous ne devriez pas en avoir besoin.

Lectures de niveau ligne Versioning

L'exemple du livre de texte pour une utilisation légitime du soupçon nolock est l'échantillonnage du rapport sur une base de données OLTP de mise à jour.

Pour prendre un exemple d'actualité. Si une grande grande banque de la rue des États-Unis a voulu exécuter un rapport horaire recherchant les premiers signes d'une course de niveau de la ville sur la rive, une requête nolock pourrait analyser les tables de transaction sommateurs dépôts en espèces et retraits d'espèces par ville. Pour un tel rapport, le petit pourcentage d'erreur provoquée par les opérations annulées de mise à jour ne réduiraient pas la valeur du rapport.

Malheureusement, il n'y a pas que la lecture des données non validées. En arrière-plan, vous pouvez finir par lire les pages deux fois (dans le cas d'une scission de la page), ou vous risquez de manquer les pages au total. Ainsi, vos résultats peuvent être grossièrement biaisée.

Consultez l'article Itzik Ben-Gan . Voici un extrait:

  

» Avec l'indicateur NOLOCK (ou le réglage de la   niveau d'isolement de la session READ   UNCOMMITTED) vous dites SQL Server   vous ne vous attendez pas la cohérence, donc il   n'y a aucune garantie. Gardez à l'esprit   que « les données incohérentes » non seulement   dire que vous pouvez voir non engagés   les changements qui ont été roulées plus tard, de retour   ou des changements de données dans un produit intermédiaire   état de la transaction. Elle a également   signifie que dans une requête simple qui   scanne toutes les tables / données index SQL Server   peut perdre la position de balayage, ou vous   pourrait finir par avoir la même ligne   deux fois . «

Je ne sais pas pourquoi vous n'êtes pas envelopper les transactions financières dans les transactions de base de données (comme lorsque vous transférez des fonds d'un compte à un autre - vous ne commettez pas d'un côté de la transaction à-un-temps - c'est pourquoi les transactions explicites existent) . Même si votre code est Braindead aux transactions commerciales que cela puisse paraître comme il est, toutes les bases de données transactionnelles ont le potentiel de faire rollbacks implicites en cas d'erreurs ou d'échec. Je pense que cette discussion est bien au-dessus de votre tête.

Si vous avez des problèmes de verrouillage, et mettre en œuvre versioning nettoyer votre code.

Aucun blocage non seulement renvoie des valeurs erronées, il renvoie des enregistrements fantômes et les doublons.

Il est une idée fausse qu'il fait toujours courir plus vite des requêtes. S'il n'y a pas de verrou sur une table, il ne fait aucune différence. S'il y a des verrous sur la table, il peut faire la requête plus rapide, mais il y a une raison serrures ont été inventés en premier lieu.

Par souci d'équité, voici deux scénarios spéciaux où un indice nolock peut fournir utilitaire

1) base de données de serveur SQL pré-2005 qui doit exécuter longue requête sur la base de données OLTP en direct cela peut être la seule façon

2) l'application mal écrit que les verrous enregistrements et retourne le contrôle à l'interface utilisateur et les lecteurs sont indéfiniment bloqués. Nolock peut être utile ici si l'application ne peut pas être fixé (tiers, etc.) et la base de données est soit avant 2005 ou versionnage ne peut être activé.

NOLOCK est équivalent à READ UNCOMMITTED, mais Microsoft dit que vous ne devriez pas l'utiliser pour les instructions UPDATE ou DELETE:

  

Pour les instructions UPDATE ou DELETE: Cette fonctionnalité sera supprimée dans une future version de Microsoft SQL Server. Évitez d'utiliser cette fonctionnalité dans de nouveaux travaux de développement, et un plan pour modifier les applications qui utilisent actuellement cette fonctionnalité.

http://msdn.microsoft.com/en-us/library/ ms187373.aspx

Cet article s'applique à SQL Server 2005, de sorte que le soutien NOLOCK existe si vous utilisez cette version. Pour code à l'épreuve (en supposant que vous avez décidé d'utiliser lit sale) que vous pouvez utiliser dans vos procédures stockées:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

Vous pouvez l'utiliser lorsque vous la lecture de données seulement, et vous ne se soucient pas vraiment de savoir si oui ou non vous pourriez obtenir retour des données qui ne sont pas encore commis.

Il peut être plus rapide sur une opération de lecture, mais je ne peux pas vraiment dire combien.

En général, je recommande pas l'utiliser -. La lecture des données non validées peut être un peu déroutant au mieux

Un autre cas où il est généralement correct est dans une base de données de rapports, où les données est peut-être déjà vieilli et écrit tout simplement ne se produisent pas. Dans ce cas, cependant, l'option doit être réglée sur la base de données ou au niveau tableau par l'administrateur en changeant le niveau d'isolation par défaut.

Dans le cas général: vous pouvez l'utiliser lorsque vous êtes très vous qu'il est normal de lire les anciennes données. La chose importante à retenir est que son très facile à obtenir que mal . Par exemple, même si elle est bien au moment où vous écrivez la requête, vous êtes sûr que quelque chose ne changera pas dans la base de données dans l'avenir pour ces mises à jour le plus important?

Je vais aussi 2 l'idée qu'il est probablement pas une bonne idée dans l'application bancaire. Ou une application d'inventaire. Ou partout où vous songez à des transactions.

La réponse est simple -. Chaque fois que votre SQL ne modifie les données, et vous avez une question qui pourrait interférer avec d'autres activités (via verrouillage)

Il est utile d'envisager pour toutes les requêtes utilisées pour les rapports, surtout si la requête prend plus que, disons, 1 seconde.

Il est particulièrement utile si vous avez des rapports de type OLAP que vous exécutez contre une base de données OLTP.

La première question à se poser, cependant, est « pourquoi suis-je inquiétais à ce sujet? » Dans mon expérience, fudging le comportement de verrouillage par défaut se produit souvent quand quelqu'un est en mode « tout essayer » ce qui est un cas où des conséquences inattendues ne sont pas improbable. Trop souvent, il est un cas d'optimisation prématurée et peut trop facilement se laisser embarqué dans une application « juste 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.

Mes 2 cents - il est logique d'utiliser WITH (NOLOCK) lorsque vous avez besoin de générer des rapports. À ce stade, les données ne changeraient pas beaucoup et vous ne voulez pas verrouiller ces enregistrements.

Si vous gérez les transactions financières alors vous ne voudrez plus jamais utiliser nolock. nolock est mieux utilisé pour sélectionner des grandes tables qui ont beaucoup mises à jour et vous ne se soucient pas si le dossier que vous obtenez pourrait être à jour.

Pour les dossiers financiers (et presque tous les autres enregistrements dans la plupart des applications) nolock bouleverserait que vous pourriez potentiellement lire les données de retour d'un enregistrement qui a été écrit pour et ne pas obtenir les données correctes.

Je l'ai utilisé pour récupérer un « lot suivant » des choses à faire. Peu importe dans ce cas quel élément exact, et j'ai beaucoup d'utilisateurs exécutant cette même requête.

Réponse courte:

Ne jamais utiliser WITH (NOLOCK).

Réponse longue:

NOLOCK est souvent exploitée comme un moyen magique pour accélérer la base de données lit, mais j'essaie d'éviter de l'utiliser autant que possible.

Le jeu de résultats peut contenir des lignes qui n'ont pas encore été commis, qui sont souvent roulaient plus tard en arrière.

Une erreur ou les résultats ensemble peut être vide, soit des lignes manquantes ou présentent la même ligne plusieurs fois.

Ceci est parce que d'autres transactions sont données en mouvement en même temps que vous le lisez.

READ COMMITTED ajoute un problème supplémentaire où les données sont endommagées dans une seule colonne où plusieurs utilisateurs changent la même cellule simultanément.

Il y a d'autres effets secondaires aussi, qui conduisent à sacrifier la vitesse augmenter vous espériez gagner en premier lieu.

On peut dire qu'il est bon d'utiliser dans les endroits où vous pouvez sortir avec elle, mais quel est le point? Je ne peux pas penser à une situation où les données corrompues est acceptable.

Ne jamais utiliser NOLOCK jamais.

(jamais)

Utilisez nolock lorsque vous êtes d'accord avec les données « sales ». Ce qui signifie nolock peut également lire des données qui est en train d'être modifié et / ou des données non validées.

Il est généralement pas une bonne idée de l'utiliser dans un environnement de transactions élevé et qui est la raison pour laquelle il n'est pas une option par défaut sur requête.

Je l'utilise avec (nolock) touche particulièrement dans les bases de données SQL Server 2000 avec une forte activité. Je ne suis pas certain qu'il est nécessaire dans SQL Server 2005 cependant. J'ai récemment ajouté que dans un soupçon SQL Server 2000 à la demande de DBA du client, parce qu'il remarquait beaucoup de verrous d'enregistrement SPID.

Tout ce que je peux dire est que l'utilisation de l'indice nous a fait pas mal et semble avoir fait le problème de blocage lui-même résoudre. Le DBA à ce client particulier a insisté essentiellement que nous utilisons l'indice.

Par ailleurs, les bases de données que je traite sont des dorsaux aux entreprises des systèmes de réclamations médicales, donc nous parlons de millions d'enregistrements et 20+ tables dans de nombreux jointures. J'ajoute généralement un WITH (nolock) pour chaque table dans la jointure (à moins qu'il soit une table dérivée, dans ce cas, vous ne pouvez pas utiliser cette indication particulière)

La réponse la plus simple est une simple question - avez-vous besoin que vos résultats soient reproductibles? Si oui, alors NOLOCKS ne convient pas en aucun cas

Si vous n'avez pas besoin répétabilité alors nolocks peuvent être utiles, surtout si vous ne disposez pas de contrôle sur tous les processus de connexion à la base de données cible.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top