Avantages de SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED


12

J'utilise SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDdans la majorité de mes requêtes SQL générales, principalement parce que cela m'a été exploré lors de l'apprentissage initial de la langue.

D'après ma compréhension, ce niveau d'isolement agit de la même manière que WITH (NO LOCK)je n'ai cependant jamais tendance à l'utiliser SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED.

  • Y at - il eu un moment que je devrais utiliser WITH (NO LOCK)plus SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED.
  • Est-ce que cela SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDempêche les autres utilisateurs d'être exclus des tables que je lis?
  • Si SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDest utilisé pour arrêter les verrous, mais que je ne lis que des données, quel est l'intérêt de les utiliser? S'agit-il uniquement de requêtes gourmandes en système qui généreraient des verrous? Vaut-il la peine de l'utiliser lors de l'exécution de requêtes qui reviendraient, disons, 5 à 10 secondes?
  • On m'a dit de ne pas utiliser SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDlors de la lecture des données qui seraient utilisées dans les mises à jour, sans doute pour éviter de mettre à jour des données sales. Serait-ce la seule raison?
  • Avec le type de base de données sur lequel je travaille, il existe un environnement de production et de test. Nous interrogerons très rarement l'environnement de production, mais lorsque j'en aurai besoin, je l'utiliserai généralement SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDdans ma requête. Je comprends que des lectures sales sont possibles avec cela. Mis à part la réception de données qui pourraient ne pas finir par être validées dans la base de données (et donc jeter mes résultats), quels autres types de «lectures sales» pourraient être possibles?

Désolé pour les questions de masse.


2
Vous pourriez lire les mêmes données deux fois, c'est une autre chute. Utiliser RU ou NO LOCK en standard est une mauvaise idée.
James Anderson

9
Je n'utiliserais pas READ UNCOMMITTEDpartout, exactement de la même manière que je n'utiliserais pas WITH (NOLOCK)partout (c'est essentiellement la même chose) blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere
Mark Sinkinson

1
Examinez les modèles d'isolement SNAPSHOT. Ils sont beaucoup plus forts que les RCU et ne bloquent pas ou ne provoquent pas de blocage. Ils ressemblent à un bon modèle par défaut pour vous (au lieu de passer par défaut à RCU!).
usr

Réponses:


25

C'est terrible, que vous l'ayez appris de cette façon (désolé!).

READ UNCOMMITTEDvous permet de lire chaque ligne, oui. Même ceux qui sont actuellement utilisés dans un INSERT, UPDATE, le DELETEfonctionnement. Ceci est très utile si vous avez besoin de jeter un coup d'œil à certaines données ou à des SELECTdéclarations critiques pour la mission où un bloc serait très dangereux.

En fait, vous risquez votre intégrité. Il peut arriver que vous lisiez une ligne, qui est actuellement utilisée pour être supprimée ou modifiée. Il peut également apparaître que vous avez lu une mauvaise valeur. Cela peut être très rare, mais cela peut arriver. Qu'est-ce que je veux dire avec ça? Eh bien, pensez à une ligne qui est très large (elle a de nombreuses colonnes avec de nombreuses colonnes longues nvarchar). Une mise à jour se produit sur cette ligne et définit de nouvelles valeurs. Dans de rares cas, il peut vous arriver que vous ne lisiez qu'une demi-rangée. Une autre chose peut arriver par exemple, si un utilisateur change ses valeurs de connexion. Il change son mail + mot de passe. Le courrier est déjà défini, mais pas le mot de passe. De cette façon, vous avez un état incohérent.

Je suggère d'oublier READ UNCOMMITTED. Utilisez-le là où vous en avez vraiment besoin.

Une autre alternative pour vous peut être d'activer l' READ_COMMITTED_SNAPSHOToption de base de données - à cet effet, vous pouvez l'utiliser en READ COMMITTED SNAPSHOTraison de la version de ligne activée dans votre tempdb. De cette façon, vous venez de lire une autre version (plus ancienne) d'une ligne. Cela ne bloquera pas vos requêtes. Mais il peut arriver que vous lisiez également une ancienne valeur, mais une ancienne valeur cohérente.

Une autre idée peut être WITH(READPAST)au lieu de WITH(NOLOCK). Vous lirez l'ancien état de la table (un peu comme dans le SNAPSHOT ISOLATION), mais vous allez ignorer toutes les lignes actuellement verrouillées à la place.


@Ionic, merci beaucoup pour la réponse! J'apprécie vraiment l'aide à ce sujet.
dmoney

@HingeSight, cela ressemble à ça, mais il y a de très bonnes chances que ce soit mon interprétation de la déclaration, merci de toute façon pour votre contribution.
dmoney

1
SNAPSHOT ISOLATIONn'a pas besoin d'être activé pour s'allumer READ COMMITTED SNAPSHOT. Seule l' READ COMMITTED SNAPSHOToption de base de données doit être activée pour que la version des lignes au lieu du verrouillage pour la cohérence de la lecture, évitant ainsi la nécessité de lectures incorrectes.
Dan Guzman

Oui, je voulais dire @ DanGuzman. Désolé, la réponse n'était pas claire à ce sujet. Je l'ai édité. :-)
Ionic

Avec READPAST, vous sauterez les enregistrements qui sont verrouillés, vous n'obtiendrez pas les anciennes valeurs - donc le seul endroit où j'ai pensé qu'il pourrait être utilisé est la gestion des files d'attente
James Z

2

Comme l'indique la réponse acceptée, oubliez d'utiliser le niveau d'isolement READ UNCOMMITTED (sauf lorsque cela est vraiment nécessaire) car vous risquez de lire des données erronées. Mais pour répondre au 3ème point de votre question, il y a deux situations que je trouve utiles:

  1. Lors de l'écriture et du test des packages SSIS SQL Server, les étapes du package peuvent être encapsulées dans une transaction. Si vous testez un package en l'exécutant étape par étape dans le débogueur SSIS, vous souhaiterez peut-être examiner les tables pendant qu'il y a des verrous sur la table. L'utilisation de SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED vous permet d'utiliser SQL Server Manager Studio pour examiner les tables pendant le débogage du package.

  2. Dans SQL Server Manager Studio, vous souhaiterez peut-être tester le code T-SQL en l'enveloppant dans une transaction pour vous donner la possibilité d'annuler les modifications. Par exemple, sur une base de données de test, vous souhaiterez peut-être restaurer les données à leur état initial dans le cadre de votre test. Si vous testez du code encapsulé par transaction et que vous souhaitez vérifier les tables verrouillées pendant que la transaction est en cours, vous pouvez utiliser SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED pour examiner les valeurs dans une autre fenêtre.

J'accepte que ce sont des utilisations assez obscures pour READ UNCOMMITTED, mais je les ai trouvées utiles dans un environnement de test.


1

Dans la plupart des bases de données, la grande majorité des activités, même les insertions, les suppressions et les mises à jour, sont en dehors des transactions explicites.

Bien sûr, READ UNCOMMITTED(Dirty Reads) peut fournir des informations incorrectes dans ces cas, mais ces informations étaient correctes 5 secondes plus tôt.

Les moments où les lectures sales produisent des résultats vraiment mauvais sont lorsqu'une transaction échoue et doit être annulée ou lors de l'exécution d'une requête sur deux tables qui sont normalement mises à jour ensemble à l'aide d'une transaction explicite.

Pendant ce temps, sur une base de données volumineuse et occupée typique qui a un rapport 100 (ou plus) à 1 de lectures aux écritures, CHAQUE requête unique (lecture) qui n'utilise pas les lectures sales ralentit le système car il doit obtenir et vérifier pour les verrous ET il est beaucoup plus probable que les transactions échouent (généralement en raison de blocages), ce qui peut entraîner des problèmes d'intégrité de la base de données plus graves.

Au lieu de cela, l'utilisation de lectures incorrectes rend le système BEAUCOUP plus rapide et plus fiable (en partie en raison de l'amélioration des performances, ce qui rend les incohérences moins susceptibles de se produire).

Bien sûr, il y a des moments où ils ne devraient pas être utilisés. Je n'aime pas définir la base de données par défaut pour utiliser le READ UNCOMMITTEDniveau d'isolement ou même utiliser l' SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDinstruction explicite au début des scripts SQL et des SP - il y a trop de chances qu'une lecture sale se produise alors qu'elle ne devrait pas. Au lieu de cela, les (NOLOCK)conseils sont une bien meilleure approche car ils indiquent explicitement que le programmeur a pensé à ce qu'ils faisaient et a décidé que, pour cette table spécifique dans cette requête spécifique, les lectures sales étaient sûres.

Si vous programmez une application pour transférer de l'argent d'un compte bancaire à un autre, vous ne devriez pas utiliser Dirty Reads. Mais la plupart des applications n'ont pas besoin de ce niveau de paranoïa.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.