En clair, quels sont les inconvénients et les avantages de l’utilisation de
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
dans une requête pour des applications .NET et des applications de services de reporting?
Ce niveau d'isolation autorise les lectures incorrectes. Une transaction peut voir des modifications non validées apportées par une autre transaction.
Pour maintenir le plus haut niveau d'isolation, un SGBD acquiert généralement des verrous sur les données, ce qui peut entraîner une perte de simultanéité et une surcharge de verrouillage. Ce niveau d'isolement détend cette propriété.
Vous voudrez peut-être consulter le article de Wikipedia sur READ UNCOMMITTED
pour quelques exemples et des lectures supplémentaires.
Vous voudrez peut-être aussi consulter le article de blog de Jeff Atwood sur la façon dont lui et son équipe ont résolu le problème de l’impasse dans les premiers jours de Stack Overflow. Selon Jeff:
Mais est-ce que
nolock
est dangereux? Pourriez-vous finir par lire des données non valides avecread uncommitted
sur? Oui, en théorie. Vous constaterez que les astronautes dont l’architecture de base de données commence à vous envoyer la science ACID ne manquent pas et que vous déclenchez l’alarme incendie du bâtiment lorsque vous leur dites que vous souhaitez essayernolock
. C'est vrai: la théorie fait peur. Mais voici ce que je pense: "En théorie, il n'y a pas de différence entre théorie et pratique. En pratique, il y en a."Je ne recommanderais jamais d'utiliser
nolock
comme solution miracle à la résolution des problèmes liés à l'huile de serpent pour les problèmes de blocage de base de données que vous pourriez rencontrer. Vous devriez d'abord essayer de diagnostiquer la source du problème.Mais en pratique, ajouter
nolock
à des requêtes dont vous savez absolument qu’il s’agit de questions simples et directes en lecture seule ne semble jamais poser problème ... Tant que vous savez ce que vous êtes faire.
Une alternative au niveau READ UNCOMMITTED
que vous pouvez envisager est le READ COMMITTED SNAPSHOT
. Citant à nouveau Jeff:
Les instantanés reposent sur une toute nouvelle méthode de suivi des modifications de données. Plus qu'un simple changement logique, le serveur doit gérer les données physiquement différemment. Une fois que cette nouvelle méthode de suivi des modifications de données est activée, il crée une copie ou un instantané de chaque modification de données. En lisant ces instantanés plutôt que des données réelles en période de conflit, les verrous partagés ne sont plus nécessaires pour les lectures et les performances globales de la base de données peuvent augmenter.
Cela peut être utile pour voir la progression de longues requêtes d'insertion, faire des estimations approximatives (comme COUNT(*)
ou approximatives SUM(*)
) etc.
En d'autres termes, les résultats renvoyés par les requêtes de lecture altérée sont corrects, à condition que vous les traitiez comme des estimations et ne preniez aucune décision critique en fonction de ceux-ci.
Mon cas d'utilisation préféré pour read uncommited
consiste à déboguer quelque chose qui se passe dans une transaction.
Démarrez votre logiciel sous un débogueur. Lorsque vous parcourez les lignes de code, il ouvre une transaction et modifie votre base de données. Pendant que le code est arrêté, vous pouvez ouvrir un analyseur de requête, le définir sur le lire le niveau d’isolation non géré et effectuer des requêtes pour voir ce qui se passe.
Vous pouvez également l'utiliser pour voir si de longues procédures sont bloquées ou si vous mettez correctement à jour votre base de données.
C’est formidable si votre entreprise aime créer des procédures stockées trop complexes.
L'avantage est que cela peut être plus rapide dans certaines situations. L'inconvénient est que le résultat peut être erroné (des données qui n'ont pas encore été validées pourraient être renvoyées) et rien ne garantit que le résultat est reproductible.
Si vous tenez à la précision, ne l'utilisez pas.
Plus d'informations sont sur MSDN :
Implémente une lecture modifiée ou un verrouillage de niveau d'isolement 0, ce qui signifie qu'aucun verrou partagé n'est émis et qu'aucun verrou exclusif n'est respecté. Lorsque cette option est définie, il est possible de lire des données non validées ou modifiées. les valeurs dans les données peuvent être modifiées et les lignes peuvent apparaître ou disparaître dans le jeu de données avant la fin de la transaction. Cette option a le même effet que de définir NOLOCK sur toutes les tables de toutes les instructions SELECT d'une transaction. C'est le moins restrictif des quatre niveaux d'isolement.
Quand est-il possible d'utiliser READ UNCOMMITTED
?
Bon: Grands rapports globaux indiquant des totaux en constante évolution.
Risky: Presque tout le reste.
La bonne nouvelle est que la majorité des rapports en lecture seule entrent dans cette catégorie Bon.
Ok pour l'utiliser:
Cela couvre probablement la majorité de ce qu'un département de Business Intelligence ferait, disons, du SSRS. L'exception est bien sûr, n'importe quoi avec des signes $ devant. De nombreuses personnes comptabilisent leur argent avec beaucoup plus de zèle que si elles étaient appliquées aux métriques de base nécessaires pour servir le client et générer cet argent. (Je blâme les comptables).
quand risqué
Tout rapport allant jusqu'au niveau de détail. Si ces détails sont nécessaires, cela implique généralement que chaque ligne sera pertinente pour une décision. En fait, si vous ne pouvez pas extraire un petit sous-ensemble sans le bloquer, c'est peut-être pour la bonne raison qu'il est actuellement édité.
Données historiques. Cela fait rarement une différence pratique, mais si les utilisateurs comprennent que les données en constante évolution ne peuvent pas être parfaites, ils ne se sentent pas les mêmes à propos des données statiques. Les lectures sales ne font pas mal ici, mais les doubles lectures peuvent parfois l'être. De toute façon, vu que vous ne devriez pas avoir de blocs sur les données statiques, pourquoi risquer cela?
Presque tout ce qui alimente une application qui possède également des fonctionnalités d'écriture.
Quand même le scénario OK n'est pas OK.
NOLOCK
sur ces tables pour quoi que ce soit.En ce qui concerne les rapports, nous l’utilisons dans toutes nos requêtes afin d’empêcher l’enlèvement d’une requête de bases de données. Nous pouvons le faire parce que nous extrayons des données historiques, pas des données à la microseconde.
Cela vous donnera des lectures sales et vous montrera des transactions qui ne sont pas encore validées. C'est la réponse la plus évidente. Je ne pense pas que ce soit une bonne idée de l'utiliser simplement pour accélérer vos lectures. Il existe d'autres moyens de le faire si vous utilisez une bonne conception de base de données.
Il est également intéressant de noter ce qui ne se passe pas. READ UNCOMMITTED n'ignore pas seulement les autres verrous de table. Cela ne cause pas non plus de verrou.
Considérez que vous générez un rapport volumineux ou que vous migrez des données hors de votre base de données à l'aide d'une instruction SELECT volumineuse et éventuellement complexe. Cela provoquera un verrou partagé qui pourrait être transformé en verrou de table partagé pendant la durée de votre transaction. D'autres transactions peuvent lire à partir de la table, mais les mises à jour sont impossibles. Cela peut être une mauvaise idée s’il s’agit d’une base de données de production puisque la production peut s’arrêter complètement.
Si vous utilisez READ UNCOMMITTED, vous ne définissez pas de verrou partagé sur la table. Vous pouvez obtenir le résultat de certaines nouvelles transactions ou ne pas en fonction du lieu où la table a été insérée et de la durée de lecture de votre transaction SELECT. Vous pouvez également obtenir deux fois les mêmes données, par exemple si une division de page se produit (les données seront copiées dans un autre emplacement du fichier de données).
Donc, s'il est très important pour vous que les données puissent être insérées tout en effectuant votre SELECT, READ UNCOMMITTED peut avoir un sens. Vous devez tenir compte du fait que votre rapport peut contenir des erreurs, mais s'il est basé sur des millions de lignes et que seules quelques-unes d'entre elles sont mises à jour lors de la sélection du résultat, cela peut être "suffisant". Votre transaction peut également échouer dans son ensemble, car l'unicité d'une ligne peut ne pas être garantie.
Une meilleure façon de procéder consiste peut-être à utiliser SNAPSHOT ISOLATION LEVEL, mais vos applications peuvent nécessiter des ajustements pour pouvoir l’utiliser. Un exemple de ceci est si votre application prend un verrou exclusif sur une ligne pour empêcher les autres de la lire et d'entrer en mode édition dans l'interface utilisateur. SNAPSHOT ISOLATION LEVEL présente également un inconvénient considérable en termes de performances (notamment sur disque). Mais vous pouvez résoudre ce problème en lançant du matériel sur le problème. :)
Vous pouvez également envisager de restaurer une sauvegarde de la base de données à utiliser pour la création de rapports ou le chargement de données dans un entrepôt de données.
Utilisez READ_UNCOMMITTED dans les cas où il est très peu probable que la source change.
N'utilisez pas READ_UNCOMMITTED lorsque vous savez que la source peut changer pendant l'opération d'extraction.