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


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 transactions élevés et beaucoup de données dans certaines tables, dans quels types de requêtes ne serait-il pas acceptable? Y at-il des cas où vous devriez toujours l'utiliser / ne jamais l'utiliser?


526
2018-03-26 17:13


origine


Réponses:


WITH (NOLOCK) équivaut à utiliser READ UNCOMMITED comme niveau d'isolation de transaction. Ainsi, vous risquez 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 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 ne sera probablement pas la bonne solution à tous les problèmes que vous essayez de résoudre avec mon humble avis.


383
2018-03-26 17:16



La question est ce qui est pire:

  • une impasse, ou
  • une mauvaise valeur?

Pour les bases de données financières, les blocages sont bien pires que les fausses valeurs. Je sais que ça sonne à l'envers, mais écoutez-moi. L'exemple traditionnel des transactions DB consiste à mettre à jour deux lignes, en les soustrayant de l'une et en l'ajoutant à une autre. C'est faux.

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

Obtenir le solde du compte temporairement faux n'est pas une grosse affaire, c'est ce que la réconciliation de fin de journée est pour. De plus, il est beaucoup plus probable qu'un découvert à partir d'un compte se produise parce que deux guichets automatiques sont utilisés en même temps 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 NOLOCK nécessaire. Donc, sauf si vous utilisez SQL Server 2000 ou plus tôt, vous ne devriez pas en avoir besoin.

Lecture supplémentaire
Versioning au niveau de la ligne


152
2018-03-26 18:08



L'exemple de livre de texte pour l'utilisation légitime de l'indicateur nolock est l'échantillonnage de rapport par rapport à une base de données OLTP à mise à jour élevée.

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


48
2018-03-26 17:55



Malheureusement, il ne s'agit pas seulement de lire des données non validées. En arrière-plan, vous pouvez lire les pages deux fois (dans le cas d’un fractionnement de la page) ou vous risquez de manquer les pages. Donc, vos résultats peuvent être très faussés.

Check-out L'article d'Itzik Ben-Gan. Voici un extrait:

"Avec l'indice NOLOCK (ou le réglage de   niveau d'isolement de la session à lire   UNCOMMITTED) vous dites à SQL Server que   vous ne vous attendez pas à la cohérence, donc il   ne sont pas des garanties. Gardez à l'esprit cependant   que les "données incohérentes" ne sont pas seulement   signifie que vous pourriez voir non engagé   les modifications qui ont été annulées plus tard,   ou des changements de données dans un intermédiaire   état de la transaction. Ça aussi   signifie que dans une requête simple   analyse toutes les données de table / index SQL Server   peut perdre la position de numérisation, ou vous   pourrait finir par obtenir la même rangée   deux fois. "


47
2018-03-29 07:30



Vous ne savez pas pourquoi vous n'emballez pas 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 un côté de la transaction à la fois - c'est la raison pour laquelle des transactions explicites existent). Même si votre code est braindead à des transactions commerciales comme cela semble, toutes les bases de données transactionnelles ont le potentiel de faire des rollbacks implicites en cas d'erreurs ou d'échec. 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 renvoie non seulement des valeurs erronées, mais renvoie des enregistrements fantômes et des doublons.

C'est une idée fausse commune qu'il fait toujours courir les requêtes plus rapidement. 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.

En toute équité, voici deux scénarios spéciaux où un indice nolock peut fournir une utilité

1) Base de données de serveur sql pré-2005 qui doit exécuter une requête longue par rapport à la base de données en direct OLTP cela peut être le seul moyen

2) 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 si la base de données est antérieure à 2005 ou si le versionnage ne peut pas être activé.


30
2018-03-03 17:01



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

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 les nouveaux travaux de développement et prévoyez de modifier les applications qui utilisent actuellement cette fonctionnalité.

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

Cet article s'applique à SQL Server 2005, donc le support pour NOLOCK existe si vous utilisez cette version. Afin d'assurer la pérennité de votre code (en supposant que vous ayez décidé d'utiliser des lectures incorrectes), vous pouvez l'utiliser dans vos procédures stockées:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED


23
2018-03-26 17:43



Un autre cas où il est généralement correct est dans une base de données de rapports, où les données sont peut-être déjà âgées 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'isolation par défaut.

Dans le cas général: vous pouvez l'utiliser quand vous êtes très Assurez-vous que vous pouvez lire les anciennes données. La chose importante à retenir est que c'est très facile de se tromper. Par exemple, même si c'est correct 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 aussi 2ème l'idée que c'est probablement ne pas une bonne idée dans l'application bancaire. Ou l'application d'inventaire. Ou n'importe où vous pensez à des transactions.


15
2018-03-26 17:19