690 votes

Qu'est-ce que "with (nolock)" dans SQL Server ?

Quelqu'un peut-il expliquer les implications de l'utilisation de with (nolock) sur les requêtes, quand l'utiliser ou ne 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 acceptable ? Y a-t-il des cas où il faut toujours l'utiliser/ne jamais l'utiliser ?

0 votes

1 votes

1 votes

Voici un excellent résumé des implications de l'utilisation de NOLOCK blogs.msdn.com/b/davidlean/archive/2009/04/06/

535voto

David M Points 45808

WITH (NOLOCK) équivaut à l'utilisation de READ UNCOMMITED comme niveau d'isolation de la transaction. Vous risquez donc de lire une ligne non validée qui sera ensuite annulée, c'est-à-dire des données qui n'ont jamais été introduites dans la base de données. Ainsi, bien que cela puisse empêcher les lectures d'être bloquées par d'autres opérations, cela comporte un risque. Dans une application bancaire avec des taux de transaction élevés, ce n'est probablement pas la bonne solution au problème que vous essayez de résoudre.

178 votes

La plupart des applications bancaires peuvent utiliser nolock en toute sécurité car elles sont transactionnelles au sens commercial du terme. Vous n'écrivez que de nouvelles lignes, vous ne les mettez jamais à jour.

57 votes

@Grauenwolf- Une ligne insérée mais non validée peut toujours conduire à des lectures erronées.

19 votes

@Saasman- Si vous n'annulez jamais les transactions, cela n'a pas d'importance. Et avec une table insérée uniquement, les chances d'un retour en arrière sont minces, voire nulles. Et s'ils se produisent, vous pourrez toujours les corriger dans le rapport de variance de fin de journée.

189voto

Jonathan Allen Points 23540

La question est de savoir ce qui est le plus grave :

  • une impasse, ou
  • une valeur erronée ?

Pour les bases de données financières, les blocages sont bien pires que les valeurs erronées. Je sais que cela peut sembler paradoxal, mais écoutez-moi. L'exemple classique des transactions de base de données est la mise à jour de deux lignes, la soustraction d'une ligne et l'ajout d'une autre. C'est une erreur.

Dans une base de données financière, vous utilisez des transactions commerciales. Cela signifie qu'il faut ajouter une ligne à chaque compte. Il est de la plus haute importance que ces transactions se terminent et que les lignes soient écrites avec succès.

Il n'est pas grave de se tromper temporairement sur le solde du compte, c'est à cela que sert la réconciliation de fin de journée. Et un découvert sur un compte est bien plus susceptible de se produire en raison de l'utilisation simultanée de deux distributeurs automatiques de billets 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 le système de gestion de l'information plus difficile à utiliser. NOLOCK nécessaires. Donc, à moins que vous n'utilisiez SQL Server 2000 ou une version antérieure, vous ne devriez pas en avoir besoin.

Pour en savoir plus
Versionnement au niveau des lignes

24 votes

Se tromper temporairement sur le solde d'un compte n'est pas grave ? Et si cette opération consiste à retirer de l'argent d'un distributeur automatique de billets sans limite de découvert ?

13 votes

@Learning : Que se passe-t-il si vous retirez l'argent 30 secondes avant que quelqu'un ne débite votre carte ? Tant que la communication ne sera pas totalement instantanée, les découverts seront une réalité.

7 votes

+1 Dans les applications financières (partout, pas seulement dans les banques), il n'y a ni mise à jour ni suppression. Même les opérations incorrectes sont corrigées par l'insertion d'enregistrements. Que signifie ce terme en anglais ? S'agit-il de "storno" ? Google ne m'a pas aidé à répondre à cette question

65voto

sqlbelle Points 296

Malheureusement, il ne s'agit pas seulement de lire des données non validées. En arrière-plan, il se peut que vous lisiez des pages deux fois (dans le cas d'une division de page), ou que vous manquiez complètement les pages. Vos résultats peuvent donc être fortement faussés.

Vérifier Article d'Itzik Ben-Gan . En voici un extrait :

" Avec l'indice NOLOCK (ou en réglant le niveau d'isolation de la session à niveau d'isolation de la session à READ UNCOMMITTED), vous indiquez à SQL Server que que vous n'attendez pas de cohérence, et qu'il n'y a donc il n'y a donc aucune garantie. Gardez toutefois à l'esprit que "i signifie pas seulement que vous pouvez voir des qui ont été annulées par la suite, ou des changements de données dans un état intermédiaire de la transaction. I signifie que dans une simple requête qui analyse toutes les données de la table/index, SQL Server peut perdre la position de balayage, ou vous la même ligne deux fois. deux fois . "

9 votes

Un peu plus loin, il explique comment obtenir deux fois la même rangée : Je vais recréer la table T1 de telle sorte que l'index clusterisé sur col1 soit défini comme un index unique avec l'option IGNORE_DUP_KEY. Cela signifie que les valeurs dupliquées ne peuvent pas exister dans col1, et aussi qu'une tentative d'insertion d'une clé dupliquée ne fera pas échouer la transaction et ne génèrera pas d'erreur, mais seulement un avertissement. Si vous n'utilisez pas cette option bizarre, vous n'avez probablement pas à vous soucier de recevoir des rangées deux fois.

1 votes

Vous pouvez toujours obtenir des lignes dupliquées même sans l'option câblée - si votre requête utilise un index qui n'est pas unique, par exemple. Ce n'est pas propre à nolock, cependant.

57voto

saasman Points 301

L'exemple type d'utilisation légitime de l'indice nolock est l'échantillonnage de rapports dans une base de données OLTP à forte mise à jour.

Prenons un exemple d'actualité. Si une grande banque américaine souhaitait établir un rapport horaire pour détecter les premiers signes d'une attaque contre la banque au niveau d'une ville, une requête nolock pourrait analyser les tables de transactions en additionnant les dépôts et les retraits d'espèces par ville. Pour un tel rapport, le minuscule pourcentage d'erreur causé par des transactions de mise à jour annulées ne réduirait pas la valeur du rapport.

33voto

Andrew Points 259

Je ne sais pas trop pourquoi vous n'intégrez pas les transactions financières dans des transactions de base de données (comme lorsque vous transférez des fonds d'un compte à un autre - vous n'engagez pas une partie de la transaction à la fois - c'est la raison pour laquelle les transactions explicites existent). Même si votre code n'est pas adapté aux transactions commerciales, comme cela semble être le cas, toutes les bases de données transactionnelles ont la possibilité de faire des retours en arrière implicites en cas d'erreurs ou d'échecs. Je pense que cette discussion vous dépasse largement.

Si vous rencontrez des problèmes de verrouillage, mettez en place un système de gestion des versions et nettoyez votre code.

L'absence de verrouillage ne renvoie pas seulement des valeurs erronées, mais aussi des enregistrements fantômes et des doublons.

On croit souvent à tort qu'il accélère toujours les requêtes. S'il n'y a pas de verrous d'é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.

Par souci d'équité, voici deux scénarios particuliers dans lesquels un indice nolock peut s'avérer utile

1) Base de données sql server d'avant 2005 qui doit exécuter des requêtes longues sur une base de données OLTP vivante - c'est 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 indéfiniment bloqués. Nolock peut être utile ici si l'application ne peut pas être corrigée (tierce partie, etc.) et si la base de données est antérieure à 2005 ou si la gestion des versions ne peut pas être activée.

13 votes

Je suis d'accord avec vous pour dire que NOLOCK ne devrait pas être utilisé pour compenser un code mal écrit. Cependant, je pense que votre attaque contre Johnathan n'est pas justifiée puisqu'il n'a jamais mentionné l'utilisation de NOLOCK. base de données des transactions. Il soulignait simplement que les applications financières ne permettent généralement pas de modifier les enregistrements (il y a évidemment des exceptions). Dans votre exemple de transfert de fonds, il dit qu'il serait étrange que vous puissiez muter la valeur du solde du compte au lieu de ajoutant une écriture de débit/crédit dans une sorte de grand livre.

25 votes

Lorsque des fonds sont transférés d'un compte à un autre dans des banques différentes, que se passe-t-il à votre avis ? Une super base de données verrouille une table à la Bank of America et une autre à la Wells Fargo ? Non. Une transaction financière est enregistrée dans chacune d'elles, puis un processus de fin de journée vérifie que tous les enregistrements correspondent.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X