web-dev-qa-db-fra.com

Les avantages de SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

J'utilise SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED Dans la majorité de mes requêtes SQL générales, principalement parce que cela m'a été expliqué lors de l'apprentissage du langage.

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

  • Y a-t-il un moment où je devrais utiliser WITH (NO LOCK) sur SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED.
  • SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED Empêche-t-il les autres utilisateurs d'être exclus des tables que je lis?
  • Si SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED Est 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? Est-il utile 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 UNCOMMITTED Lors 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, j'utiliserai généralement SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED Dans 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.

12
dmoney

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

READ UNCOMMITTED Vous permet de lire chaque ligne, oui. Même ceux qui sont actuellement utilisés dans une opération INSERT, UPDATE, DELETE. Ceci est très utile si vous devez jeter un coup d'œil à certaines données ou à des missions critiques SELECT - Déclarations 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-ligne. Une autre chose peut se produire, par exemple, si un utilisateur modifie 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ù c'est vraiment nécessaire.

Une autre alternative pour vous peut être d'activer l'option de base de données READ_COMMITTED_SNAPSHOT - vous pouvez donc utiliser READ COMMITTED SNAPSHOT En raison 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.

26
Ionic

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 alors 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 à l'é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.

2
Ubercoder

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.

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 ratio de lectures/écritures de 100 (ou plus) à 1, 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 sales 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 UNCOMMITTED niveau d'isolement ou même en utilisant _ SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED instruction 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, le (NOLOCK) les 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 ce tableau 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 devez pas utiliser Dirty Reads. Mais la plupart des applications n'ont pas besoin de ce niveau de paranoïa.

1
Simon Holzman