Quelle est la différence entre la lecture non répétable et la lecture fantôme?
J'ai lu l'article Isolation (systèmes de base de données) de Wikipedia , mais j'ai quelques doutes. Dans l'exemple ci-dessous, que va-t-il se passer: la lecture non répétable et la lecture fantôme ?
Transaction ASELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1
PRODUCTION:
1----MIKE------29019892---------5000
Transaction B
UPDATE USERS SET amount=amount+5000 where ID=1 AND accountno=29019892;
COMMIT;
Transaction A
SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1
Un autre doute est, dans l'exemple ci-dessus, quel niveau d'isolement doit être utilisé? Et pourquoi?
Réponses:
De Wikipédia (qui a des exemples intéressants et détaillés pour cela):
et
Exemples simples:
select sum(x) from table;
renvoie un résultat différent même si aucune des lignes affectées n'a été mise à jour, si des lignes ont été ajoutées ou supprimées.Le niveau d'isolement dont vous avez besoin dépend de votre application. Il y a un coût élevé pour un «meilleur» niveau d'isolement (comme une simultanéité réduite).
Dans votre exemple, vous n'aurez pas de lecture fantôme, car vous ne sélectionnez qu'à partir d'une seule ligne (identifiée par la clé primaire). Vous pouvez avoir des lectures non répétables, donc si cela pose un problème, vous voudrez peut-être avoir un niveau d'isolement qui empêche cela. Dans Oracle, la transaction A peut également émettre un SELECT FOR UPDATE, puis la transaction B ne peut pas modifier la ligne tant que A n'est pas terminé.
la source
Une façon simple que j'aime y penser est:
Les lectures non répétables et fantômes ont à voir avec les opérations de modification des données d'une transaction différente, qui ont été validées après le début de votre transaction, puis lues par votre transaction.
Les lectures non répétables se produisent lorsque votre transaction lit des MISES À JOUR validées à partir d'une autre transaction. La même ligne a maintenant des valeurs différentes de celles du début de votre transaction.
Les lectures fantômes sont similaires, mais lors de la lecture à partir d' INSERTS validés et / ou de DELETES à partir d'une autre transaction. De nouvelles lignes ou lignes ont disparu depuis le début de la transaction.
Les lectures incorrectes sont similaires aux lectures non répétables et fantômes, mais concernent la lecture de données NON ENGAGÉES et se produisent lorsqu'une mise à jour, une insertion ou une suppression d'une autre transaction est lue et que l'autre transaction n'a PAS encore validé les données. Il lit des données "en cours", qui peuvent ne pas être complètes et ne jamais être validées.
la source
Comme expliqué dans cet article , l' anomalie de lecture non répétable se présente comme suit:
Dans cet article sur Phantom Read , vous pouvez voir que cette anomalie peut se produire comme suit:
Ainsi, alors que la lecture non répétable s'applique à une seule ligne, la lecture fantôme concerne une plage d'enregistrements qui satisfont à un critère de filtrage de requête donné.
la source
Lire les phénomènes
UPDATE
requête d'une autre transactionINSERT
ouDELETE
d'une autre transactionRemarque : les instructions DELETE d'une autre transaction ont également une très faible probabilité de provoquer des lectures non répétables dans certains cas. Cela se produit lorsque l'instruction DELETE, malheureusement, supprime la même ligne que votre transaction actuelle interrogeait. Mais c'est un cas rare, et beaucoup plus improbable dans une base de données contenant des millions de lignes dans chaque table. Les tables contenant des données de transaction ont généralement un volume de données élevé dans n'importe quel environnement de production.
Nous pouvons également observer que les MISES À JOUR peuvent être un travail plus fréquent dans la plupart des cas d'utilisation plutôt que de réelles INSERT ou DELETES (dans de tels cas, le danger de lectures non répétables reste seulement - les lectures fantômes ne sont pas possibles dans ces cas). C'est pourquoi UPDATES est traité différemment de INSERT-DELETE et l'anomalie résultante est également nommée différemment.
Il existe également un coût de traitement supplémentaire associé à la gestion des INSERT-DELETE, plutôt qu'à la gestion des MISES À JOUR.
Avantages des différents niveaux d'isolement
Alors pourquoi ne pas simplement définir la transaction SERIALIZABLE à tout moment? Eh bien, la réponse à la question ci-dessus est: le paramètre SERIALIZABLE rend les transactions très lentes , ce que nous ne voulons pas non plus.
En fait, la consommation de temps de transaction est au taux suivant:
Le paramètre READ_UNCOMMITTED est donc le plus rapide .
Résumé
En fait, nous devons analyser le cas d'utilisation et décider d'un niveau d'isolement afin d'optimiser le temps de transaction et d'éviter la plupart des anomalies.
Notez que les bases de données par défaut ont le paramètre REPEATABLE_READ.
la source
Il existe une différence d'implémentation entre ces deux types de niveaux d'isolement.
Pour une "lecture non répétable", un verrouillage de ligne est nécessaire.
Pour la "lecture fantôme", un verrouillage de portée est nécessaire, même un verrouillage de table.
Nous pouvons implémenter ces deux niveaux en utilisant un protocole de verrouillage en deux phases .
la source
Dans un système avec des lectures non répétables, le résultat de la deuxième requête de la transaction A reflétera la mise à jour de la transaction B - il verra le nouveau montant.
Dans un système qui autorise les lectures fantômes, si la transaction B devait insérer une nouvelle ligne avec ID = 1, la transaction A verra la nouvelle ligne lorsque la deuxième requête est exécutée; c'est-à-dire que les lectures fantômes sont un cas particulier de lecture non répétable.
la source
La réponse acceptée indique surtout que la prétendue distinction entre les deux n’est en fait pas du tout significative.
Si "une ligne est récupérée deux fois et les valeurs à l'intérieur de la ligne diffèrent entre les lectures", alors ce ne sont pas la même ligne (pas le même tuple dans le bon discours RDB) et c'est alors en effet par définition aussi le cas que "la collection de les lignes renvoyées par la deuxième requête sont différentes de la première ".
Quant à la question "quel niveau d'isolement doit être utilisé", plus vos données sont d'une importance vitale pour quelqu'un, quelque part, plus il sera vrai que Serializable est votre seule option raisonnable.
la source
Je pense qu'il y a une différence entre la lecture non répétable et la lecture fantôme.
Le non-répétable signifie qu'il y a des transactions de remorquage A et B. si B peut remarquer la modification de A, alors peut-être se produire une lecture sale, donc nous laissons B remarquer la modification de A après la validation de A.
Il y a un nouveau problème: nous laissons B remarquer la modification de A après la validation de A, cela signifie que A modifier une valeur de ligne que le B tient, parfois B relira la ligne, donc B obtiendra une nouvelle valeur différente avec la première fois que nous get, nous l'appelons Non répétable, pour résoudre le problème, nous laissons le B se souvenir de quelque chose (car je ne sais pas encore ce dont on se souviendra) quand B démarre.
Pensons à la nouvelle solution, nous pouvons remarquer qu'il y a également un nouveau problème, car nous laissons B se souvenir de quelque chose, donc quoi qu'il se soit passé dans A, le B ne peut pas être affecté, mais si B veut insérer des données dans la table et B Vérifiez le tableau pour vous assurer qu'il n'y a pas d'enregistrement, mais ces données ont été insérées par A, donc peut-être se produire une erreur. Nous l'appelons Phantom-read.
la source
la lecture non répétable est un niveau d'isolement et la lecture fantôme (lecture de la valeur validée par d'autres transactions) est un concept (type de lecture, par exemple lecture sale ou lecture d'instantané). Le niveau d'isolement de lecture non répétable permet la lecture fantôme mais pas les lectures modifiées ou les lectures d'instantané.
la source