Meilleure situation pour utiliser le niveau d'isolement READ UNCOMMITTED

10

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.

Peter Mortensen
la source

Réponses:

20

Je utiliser READ_UNCOMMITTED(ou NOLOCK) lors de l' interrogation des bases de données de production de SSMS , mais pas systématiquement 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/ suis NOLOCKlargement 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 versionnement des lignes ( SNAPSHOTou READ_COMMITTEDavec l' READ_COMMITTED_SNAPSHOToption de base de données ON) et / ou une attention au réglage des requêtes et des index.

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

Dan Guzman
la source
7

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 la base de code entière pour les conditions de course avec RCSI.

Cependant, cela pourrait ne pas convenir. Vous devrez peut-être passer un peu plus de temps à aimer et à prendre soin de tempdb, et à vous assurer que personne ne laisse une transaction ouverte qui fait grandir le magasin de versions (et tempdb) et remplir 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 l' ensemble de leur application . 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 d'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.

Erik Darling
la source
5
Et si le problème concerne uniquement la génération de rapports sur les données OLTP, déchargez-les dans un secondaire en lecture seule (AG, envoi de journaux, réplication ou roll-your-own).
Aaron Bertrand
3
@AaronBertrand Et puis ils auraient un deuxième serveur à surveiller;)
Erik Darling
5

À mon humble avis, le seul 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 pouvez voir ce qu'il fait alors, par exemple, qu'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.

Gaius
la source
3

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

Il est étonnamment rare que des lignes de données individuelles changent à mi-parcours, et le rapport de lecture / écriture est comme 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 ne change, il change d' 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 soins de santé SQL, je n'en ai jamais vu 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.

Faut- il l'utiliser? 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.

James
la source
4
juste pour info, il est possible de lire des lignes partiellement écrites avec nolock.
Max Vernon
1
Oof! J'ai vraiment besoin que mon patron m'achète un autre serveur pour que je puisse me connecter expédier ces trucs ....
James
3
Vous pourriez être intéressé par cet article de blog astucieux de Paul White sur LIRE NON ENGAGÉ
Josh Darnell
1

READ_UNCOMMITTED/NOLOCKest 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 une simple requête de sélection avec NOLOCKsur la table cible périodiquement pour voir si elle progresse sans problème (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 la group byrequête avec NOLOCKpour savoir si le nombre de changements d'état change constamment).

GirKarr
la source
0

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 l'article d' Itzik Ben-Gan

SQLRaptor
la source
3
Les lignes manquantes et la lecture de lignes plusieurs fois est également possible au niveau de validation par défaut. Si une colonne de clé d'index est mise à jour pendant l'analyse et qu'elle se déplace.
Martin Smith
La discussion parallèle sur cette réponse a été déplacée vers le chat .
Paul White 9