web-dev-qa-db-fra.com

Meilleure situation pour utiliser le niveau d'isolement READ UNCOMMITTED

Comme nous le savons tous, READ UNCOMMITTED est le niveau d'isolement le plus bas dans lequel des choses comme les lectures sales et les lectures fantômes peuvent s'accumuler. Quel est le meilleur moment pour utiliser ce niveau d'isolement et pour quelles raisons pourrait-il être utilisé?

En fait, j'ai lu les réponses avant, mais je ne pouvais pas le comprendre complètement car il n'y avait pas assez d'exemples.

10
user123215

J'utilise READ_UNCOMMITTED (ou NOLOCK) lors de l'interrogation des bases de données de production à partir de SSMS mais pas systématiquement à partir du code d'application. Cette pratique (avec un indice de requête MAXDOP 1) permet de garantir que les requêtes occasionnelles pour l'analyse et le dépannage des données n'affectent pas la charge de travail de production, étant entendu que les résultats peuvent ne pas être corrects.

Malheureusement, je vois READ_UNCOMMITTED/NOLOCK largement utilisé dans le code de production pour éviter le blocage au détriment de l'intégrité des données. La solution appropriée est un niveau d'isolation de version des lignes (SNAPSHOT ou READ_COMMITTED avec le READ_COMMITTED_SNAPSHOT option de base de données ON) et/ou attention au réglage des requêtes et des index.

J'ai récemment revu le code d'un proc où le seul changement était de supprimer NOLOCK car il retournait parfois des résultats erronés. Supprimer NOLOCK était une bonne chose mais, sachant que les lignes manquées ou dupliquées se produisent généralement pendant analyses de l'ordre d'allocation des grandes tables, j'ai suggéré de refactoriser également pour utiliser un UNION ALL technique pour promouvoir une utilisation efficace de l'index. La requête s'exécute maintenant en quelques millisecondes avec des résultats corrects, le meilleur de tous les mondes.

20
Dan Guzman

Je pense que c'est bien dans certaines circonstances, tant que vous acceptez les conséquences et que vous n'avez pas d'autres options.

Pour d'autres options, je pousserais les gens à utiliser Read Committed Snapshot Isolation (RCSI) pour de nouvelles applications, ou SNAPSHOT ISOLATION (SI) pour les applications plus anciennes, où vous ne pouvez pas facilement tester l'intégralité de la base de code pour les conditions de course avec RCSI.

Cependant, cela pourrait ne pas convenir. Vous devrez peut-être passer plus de temps à aimer et à prendre soin de tempdb, et à vous assurer que personne ne laisse une transaction ouverte qui fait que le magasin de versions (et tempdb) grandisse et remplisse le disque.

Si vous ne disposez pas d'un administrateur de base de données ou d'une personne dont le travail consiste à surveiller et à gérer votre serveur SQL, ces options peuvent être périlleuses. Plus généralement, tout le monde n'a pas le contrôle total du code allant sur son serveur où il peut modifier la chaîne ou le code de connexion pour demander SI pour les requêtes problématiques.

En plus de cela, la plupart des gens n'ont pas de problèmes de verrouillage avec leur application entière . Ils ont des problèmes avec des choses comme les rapports sur les données OLTP. Si vous pouvez accepter les compromis de NOLOCK/RU en échange de ces rapports qui ne sont pas bloqués par les écrivains, allez-y.

Assurez-vous simplement de comprendre ce que cela signifie. Cela ne signifie pas que votre requête ne prend aucun verrou, cela signifie qu'elle ne respecte pas les verrous supprimés par les autres requêtes.

Et bien sûr, si votre problème est le verrouillage de l'écrivain/écrivain, la seule option qui vous aidera est SI, mais cela prendrait une quantité incroyable de travail de développeur pour l'implémenter correctement avec la gestion des erreurs, etc.

7
Erik Darling

À mon humble avis niquement cas d'utilisation valide pour READ UNCOMMITTED sur un système moderne est lors du débogage d'une session à partir d'une autre en cours de développement, de sorte que vous puissiez voir ce qu'il fait tout en ex. un proc stocké est toujours en cours d'exécution. Il ne serait jamais normalement utilisé dans un système de production. Il peut y avoir un gain de performance mineur mais à long terme, cela n'en vaudra jamais la peine.

5
Gaius

Nous l'utilisons tout le temps dans les soins de santé.

Il est étonnamment rare que des lignes de données individuelles changent en cours de requête, et le rapport de lecture/écriture est de 10 000/1 - et la plupart sont des insertions, pas des mises à jour. Par exemple, lorsque l'interface de laboratoire écrit les résultats de laboratoire d'un patient dans la base de données, ces valeurs ne changeront jamais.

Lorsque les données change changent, elles changent une ligne à la fois. Personne ne met à jour des colonnes entières (sauf un DBA, quand ils gâchent vraiment mal).

De l'autre côté, nous exécutons un tas de requêtes pour rechercher des choses comme les patients revenant aux urgences en 72 heures ou moins, ce qui martèle absolument les tables.

En 10 ans de SQL dans les soins de santé, je n'ai jamais vu un Rollback Transaction. Je veux entrer et sortir sans perturber l'expérience de l'utilisateur final. S'il y a un risque élevé de ralentir la base de données OLTP et un faible risque d'obtenir de mauvaises données, je vais NOLOCK.

Devrions nous l'utilisons? Peut-être peut-être pas. D'une manière générale, je ne dirais pas que la plupart des bases de données d'application sur lesquelles j'ai travaillé sont bien conçues. Ils sont normalement pleins d'anti-motifs.

3
James

READ_UNCOMMITTED/NOLOCK est une bonne option lorsque l'exactitude des données n'est pas vraiment l'objectif principal. Parfois, lorsqu'un nombre agrégé approximatif suffit. Par exemple: Il existe des procédures stockées qui sont utilisées pour INSÉRER ou METTRE À JOUR les tables. Parfois, le nombre d'enregistrements à mettre à jour ou à insérer est énorme (des milliers d'enregistrements). Au cours de ces exécutions de procédures stockées, nous pouvons exécuter périodiquement une requête de sélection simple avec NOLOCK sur la table cible pour voir si elle progresse correctement (pour la requête de mise à jour, si vous avez une colonne de changement de statut pour les enregistrements mis à jour, nous pouvons utiliser cette colonne pour exécuter group by interrogez avec NOLOCK pour savoir si le nombre de changements d'état change constamment).

1
GirKarr

Sachez que READ UNCOMMITTED introduit des problèmes de cohérence supplémentaires, pas seulement des lectures incorrectes. Selon la méthode d'accès, vous pouvez manquer des lignes ou même lire la même ligne plusieurs fois. Si vous êtes intéressé par les détails, lisez Article d'Itzik Ben-Gan

0
SQLRaptor