Je pense que les niveaux d'isolement ci-dessus sont si semblables. Quelqu'un pourrait-il décrire avec de beaux exemples quelle est la principale différence?
Je pense que les niveaux d'isolement ci-dessus sont si semblables. Quelqu'un pourrait-il décrire avec de beaux exemples quelle est la principale différence?
Réponses:
La lecture validée est un niveau d'isolement qui garantit que toutes les données lues ont été validées au moment de la lecture. Cela empêche simplement le lecteur de voir toute lecture intermédiaire, non engagée et «sale». Il ne fait aucune promesse que si la transaction réémet la lecture, trouvera les mêmes données, les données sont libres de changer après avoir été lues.
La lecture répétable est un niveau d'isolement plus élevé, qui en plus des garanties du niveau de lecture engagé, garantit également que les données lues ne peuvent pas changer , si la transaction lit à nouveau les mêmes données, elle trouvera les données précédemment lues en place, inchangées et disponible pour lecture.
Le prochain niveau d'isolement, sérialisable, constitue une garantie encore plus forte: en plus de toutes les garanties de lecture répétables, il garantit également qu'aucune nouvelle donnée ne peut être vue par une lecture ultérieure.
Supposons que vous ayez un tableau T avec une colonne C avec une ligne, disons qu'il a la valeur «1». Et considérez que vous avez une tâche simple comme la suivante:
BEGIN TRANSACTION;
SELECT * FROM T;
WAITFOR DELAY '00:01:00'
SELECT * FROM T;
COMMIT;
C'est une tâche simple qui émet deux lectures à partir du tableau T, avec un délai de 1 minute entre elles.
Si vous suivez la logique ci-dessus, vous pouvez rapidement réaliser que les transactions SERIALISABLES, bien qu'elles puissent vous faciliter la vie, bloquent toujours complètement toutes les opérations simultanées possibles, car elles nécessitent que personne ne puisse modifier, supprimer ou insérer une ligne. Le niveau d'isolement des transactions par défaut de l' System.Transactions
étendue .Net est sérialisable, ce qui explique généralement les performances abyssales qui en résultent.
Et enfin, il y a aussi le niveau d'isolement SNAPSHOT. Le niveau d'isolement SNAPSHOT offre les mêmes garanties que sérialisable, mais pas en exigeant qu'aucune transaction simultanée ne puisse modifier les données. Au lieu de cela, il oblige chaque lecteur à voir sa propre version du monde (c'est son propre «instantané»). Cela le rend très facile à programmer ainsi que très évolutif car il ne bloque pas les mises à jour simultanées. Cependant, cet avantage a un prix: une consommation supplémentaire de ressources serveur.
Lectures supplémentaires:
L'état de la base de données est conservé dès le début de la transaction. Si vous récupérez une valeur dans session1, puis mettez à jour cette valeur dans session2, la récupérer à nouveau dans session1 renverra les mêmes résultats. Les lectures sont reproductibles.
session1> BEGIN;
session1> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> BEGIN;
session2> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> UPDATE names SET firstname = 'Bob' WHERE id = 7;
session2> SELECT firstname FROM names WHERE id = 7;
Bob
session2> COMMIT;
session1> SELECT firstname FROM names WHERE id = 7;
Aaron
Dans le cadre d'une transaction, vous récupérerez toujours la dernière valeur validée. Si vous récupérez une valeur dans session1, mettez-la à jour dans session2, puis récupérez-la dans session1à nouveau, vous obtiendrez la valeur telle que modifiée dans session2. Il lit la dernière ligne validée.
session1> BEGIN;
session1> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> BEGIN;
session2> SELECT firstname FROM names WHERE id = 7;
Aaron
session2> UPDATE names SET firstname = 'Bob' WHERE id = 7;
session2> SELECT firstname FROM names WHERE id = 7;
Bob
session2> COMMIT;
session1> SELECT firstname FROM names WHERE id = 7;
Bob
Logique?
Simplement la réponse selon ma lecture et ma compréhension de ce fil et de la réponse @ remus-rusanu est basée sur ce scénario simple:
Il existe deux processus A et B. Le processus B lit le tableau X Le processus A écrit dans le tableau X Le processus B lit à nouveau le tableau X.
Vieille question qui a déjà une réponse acceptée, mais j'aime penser à ces deux niveaux d'isolement en termes de la façon dont ils modifient le comportement de verrouillage dans SQL Server. Cela pourrait être utile pour ceux qui déboguent des blocages comme je l'étais.
LIRE ENGAGÉ (par défaut)
Les verrous partagés sont pris dans SELECT, puis libérés à la fin de l'instruction SELECT . C'est ainsi que le système peut garantir qu'il n'y a pas de lectures incorrectes de données non validées. D'autres transactions peuvent toujours modifier les lignes sous-jacentes une fois votre SELECT terminé et avant la fin de votre transaction.
REPEATABLE READ
Les verrous partagés sont pris dans SELECT, puis libérés uniquement une fois la transaction terminée . C'est ainsi que le système peut garantir que les valeurs que vous lisez ne changeront pas pendant la transaction (car elles restent verrouillées jusqu'à la fin de la transaction).
Essayer d'expliquer ce doute avec des diagrammes simples.
Lire validée: ici, dans ce niveau d'isolement, la transaction T1 lira la valeur mise à jour du X validé par la transaction T2.
Lecture répétable: dans ce niveau d'isolement, la transaction T1 ne prendra pas en compte les modifications validées par la transaction T2.
Je pense que cette image peut aussi être utile, elle m'aide comme référence lorsque je veux me souvenir rapidement des différences entre les niveaux d'isolement (merci à kudvenkat sur youtube)
Veuillez noter que la répétition en lecture répétable concerne un tuple, mais pas l'ensemble du tableau. Dans les niveaux d'isolement ANSC, une anomalie de lecture fantôme peut se produire, ce qui signifie que lire une table avec la même clause where peut renvoyer deux fois différents jeux de résultats différents. Littéralement, ce n'est pas répétable .
Mon observation sur la solution initiale acceptée.
Sous RR (mysql par défaut) - Si un tx est ouvert et qu'un SELECT a été déclenché, un autre tx ne peut PAS supprimer une ligne appartenant au jeu de résultats READ précédent tant que le tx précédent n'est pas validé (en fait, la suppression de l'instruction dans le nouveau tx se bloquera simplement) , mais le tx suivant peut supprimer toutes les lignes de la table sans aucun problème. Btw, une prochaine LECTURE dans le tx précédent verra toujours les anciennes données jusqu'à ce qu'elles soient validées.