TME Contrôle de concurrence
Les objectifs: mettre en place des situations de concurrence entre transactions. Comprendre les mécanismes de contrôle de concurrence.
Documentation
- Livre Concepts: chapitre 13.
- Livre Performance tuning: chapitre 10
- Les vues du dictionnaire : dba_blockers, dba_waiters, v$lock, v$session_event, v$session_wait, v$session, v$active_session_history
- Divers : une notice pour identifier quel nuplet est à l'origine d'un blocage
Préparation
les vues mesurant les durées d'attente (v$waitstat, etc...) ne sont renseignées que si le paramètre d'initialisation timed_statistics vaut true. Vérifier la valeur de ce paramètre en interrogant la vue v$parameter. Eventuellement modifier sa valeur avec la commande :
- SQL> alter session set timed_statistics = true
- Schema: Employe(num, ...)
- lecture d'un tuple: L(A) : select * from Employe where num = 1
écriture
- E(A) : update Employe set age=age+1 where num=1
- E(B) : update Employe set age=age+1 where num=2
Ouvrir 2 fenêtres de terminal
Dans chaque fenêtre
- lancer sqlplus etuNN/etuNN@ora2 dans chaque fenêtre
Choisir le niveau d'isolation (read committed ou serializable)
- SQL> alter session set isolation_level = read committed
- le niveau d'isolation est fixé pour toutes les transactions d'une session (= un terminal)
- il est possible de changer le niveau d'isolation en début de transaction (juste après un commit)
Ex1 Verrouillage
Réaliser les expérience montrant le fonctionnement du gestionnaire de verrous d'oracle.
lecture non bloquante
- L1A ne bloque pas L2A
T1 | L(A) | |
T2 | L(A) |
- L1A ne bloque pas E2A
T1 | L(A) | |
T2 | E(A) |
lecture non bloquée
- L2A non bloquée par L1A (voir ci-dessus)
- L2A non bloquée par E1A
T1 | E(A) | commit | ||
T2 | L(A) | commit |
T2 voit-elle l'écriture faite précédemment par T1 ? Quel est l'odre en série équivalent à cette exécution ? Est-ce le même que l'ordre chronologique des commit, pourquoi ?
Ecriture bloquante
E2A bloquée par E1(A): Vérifier que E2(A) est en attente d'un VX sur A.
T1 | E(A) | |
T2 | E(A): attente |
Quelles requêtes sur le dictionnaire affichent les infos suivantes ?
- la liste des verrous détenus par T1
- la liste des transactions en attente du verrou sur A détenu par T1
Que se passe-t-il lorsque T1 valide, lorsque T1 abandonne ?
T1 | E(A) | commit | |
T2 | E(A): attente | .... |
Recommencer en modifiant les niveaux d'isolation de T1 et de T2. Est ce possible de garantir le niveau d'exécution sérializable pour T2, lorsque T1 est au niveau read committed ? Commenter les résultats obtenus.
Granularité du verrouillage
- Vérifier qu'E2(B) n'est pas bloquée par E1(A)
Une lecture est-t-elle bloquée par une écriture qui modifie le schéma de la base ?
- M(Emp) : alter table Emp ...
T1 | M(Emp) | |
T2 | L(A): attente ? |
- Une écriture E2(A) est-ellle bloqué par M1(Emp)
- Une écriture M2(Emp) est-ellle bloqué par E1(A)
- Quels sont les verrous demandés avant de traiter E(A) et M(Emp) ?
Interblocage
Vérifier l'interblocage suivant:
T1 | E(A) | E(B) | |
T2 | E(B) | E(A) |
Comment résoudre l'interblocage sans abandonner T2 ? Donner une situation d'interblocage qui implique 3 transactions (sans attente mutuelle directe entre 2 transactions). On souhaite abandonner la transaction la plus récente. Quelle requête du dictionnaire affiche la date de début des transactions actives ? Voir l'estampille system change number (SCN) d'une transaction.
Ex2 Sérialisation
Pour cet exercice, le niveau d'isolation des sessions est serializable
- SQL> alter session set isolation_level = serializable
La séquence suivante est-elle sérializable ?
T1 | L(A) | E(A) | ||
T2 | E(A) | commit |
Que se passe-t-il ?
La séquence suivante est-t-elle sérializable ? Si oui, quel est l'ordre en série équivalent?
T1 | L(B) | E(A) | ||
T2 | E(A) | commit |
Pourquoi est-t-elle refusée ?
Ex3 Impact du verrouillage sur les performances
La granularité du verrouillage, au niveau d'un tuple ou d'une table toute entière, a-t-elle un effet sur les performances ?
1) Réaliser une expérience avec 4 sessions effectuant des mises à jour en concurrence. Chaque session exécute une procédure qui traite une séquence de 1000 écritures.
- E(n): update Emp set age = age+1 where num = v . La valeur v de l'attribut num est choisie aléatoirement.
- valider chaque mise à jour individuellement (commit).
Déterminer le nombre total de mise à jour qui ont été retardées par l'attente d'un verrou.
2) Reprendre l'expérience en augmentant le nombre de mises à jour par transaction : effectuer un commit toutes les N mises à jour. Choisir N=100. A quel moment les verous sont-ils relachés ? A partir de quelle valeur de N observe-t-on un interblocage ? Lorsqu'il n'y a pas d'interblocage, déterminer le nombre total de mises à jour qui ont été retardées par l'attente d'un verrou.
3) Modifier l'expérience en demandant un verrou sur la table Emp avant chaque mise à jour, puis en le relachant juste après (commit).
- lock table emp ...; update ...; comit;
Déterminer le nombre total de mise à jour qui ont été retardées par l'attente d'un verrou. Observe-t-on un interblocage lorsque on augmente de nombre N de mises à jour par transaction ? Pourquoi ? Donner pour différentes valeurs de N, la durée d'attente totale de chaque session.
Questions facultatives
4)La session 1 effectue des transactions avec N mises à jour par transactions. Par contre, les 3 autres sessions effectuent une seule mise à jour par transaction. Dans ces conditions, un interblocage peut-il se produire ? Pourquoi ?
Modifier la session 1 pour que son niveau d'isolation soit serializable.
A partir de quelle valeur de N observe-t-on l'occurence d'une séquence non sérializable ? Les séquences non sérializables étant détectées et refusées par Oracle, proposer une solution pour poursuivre la session 1 en recommençant les transactions contenant une mise à jour refusée.
5) Proposer une expérience montrant le relachement partiel des verrous lors d'un rollback to savepoint. Cela a-t-il un impact sur les transactions déja en attente du verou avant le rollback to savepoint ? Pourquoi?