la page du cours
Transactions, reprise sur panne, concurrence
1 Transactions et reprise sur panne
1.1 Transactions sous Oracle
-
Une transaction est une séquence d'ordres SQL
exécutés tous ou aucun.1
- Le début d'une transaction est le premier ordre qui suit :
-
connexion au serveur, ou
- fin de transaction.
Les fins de transaction :
-
annulation
- confirmation (transaction dîte alors validée).
- listes des confirmations :
-
explicite : commit
- implicites :
-
tous ordres de mise à jour de schéma
- commande de déconnexion du mode interactif (ou application)
- grant (ordre de gestion de la confidentialité, vu
bientôt)
- en mode de confirmation automatique : toutes mises à jour de
l'instance2
effet : confirme toutes mises à jour de l'instance depuis le
début de la transaction
- listes des annulations :
-
explicite : rollback
- implicite : déconnexion anormale (autre qu'ordre explicite de
déconnexion interactif ou application)
effet : annule toutes mises à jour de l'instance depuis le
début de la transaction
- remarques :
-
au cours transaction : ``table virtuelle locale'', différente
de la table réelle visible par tous clients
- un ordre peut échouer sans annuler la transaction (ex :
insertion avec colonnes incorrectes)
- rapport avec la persistance : une mise à
jour3 persiste ssi
elle fait partie d'une transaction validée
- recommandations :
-
ne pas mettre dans la même transaction des mises à jour non
corrélées logiquement
- expliciter toutes les confirmations et annulations par des
commit ou des rollback.
1.2 Analyse de programme
On s'intéresse ici à prévoir le contenu de la base à chaque
instant au cours du déroulement d'une séquence d'ordres
SQL.4
On considère une table t(a integer, b integer) contenant à
l'origine le(s) n-uplet(s) indiqué(s) au début de chaque
tableau. Tout ordre dessus est autorisé à tout utilisateur. On
considère un client p1 qui lance les séquences d'ordres
suivantes, immédiatement après sa connexion, avec le mode de
confirmation automatique non activé. Un autre client quelconque est
représenté par p2. Compléter les tableaux suivants. Indiquez
le début et la fin de chaque transaction. Vérifiez ensuite sur
machine avec sqlplus.
ordres p1 |
t ds trans p1 |
t vue par p2 |
|
(1,2) |
(1,2) |
insert (3,4) |
|
|
insert (1,2) |
|
|
rollback |
|
|
commit |
|
|
insert (1,2) |
|
|
exit |
|
|
ordres p1 |
t ds trans p1 |
t vue par p2 |
|
(1,2) |
(1,2) |
rollback |
|
|
insert (1,2) |
|
|
alter t add (c integer) |
|
|
update b = 3 where a = 1 |
|
|
panne : tapez ctl-\ |
|
|
ordres p1 |
t dans transaction p1 |
t vue par p2 |
|
(1,2) |
(1,2) |
insert (3,4) |
|
|
insert (5,6) |
|
|
set autocommit on |
|
|
insert (7,8) |
|
|
rollback |
|
|
insert (1,2,3,4) |
|
|
delete where a = 1 |
|
|
panne : tapez ctl-\ |
|
|
1.3 Construction de programme
Il s'agit ici de gérer vous-même la reprise sur panne en
plaçant les débuts et fins de transaction aux bons endroits pour
préserver la cohérence de votre base en cas de panne. Faites
l'exercice suivant en mode interactif, puis programmez-le sous Java.
Testez dans les deux cas.
Vous arrivez dans une SSII dans laquelle on vous confie la séquence
d'ordres suivante, censée gérer une situation d'achat de billet
sur les tables Voyage(client, destination, km), et Banque(client, montant) :
insert into Voyages
values(Jules, Saint Lucien, 100) ;
update Banque
set montant -= 100
where client = Jules ;
-
Concrétisez l'exemple en considérant un ou deux n-uplets dans chaque table.
- Enoncez la contrainte que doivent satisfaire les données de
votre exemple.
- Ce programme est-il correct ? Sinon, donnez tous les
contre-exemples (pannes), en donnant à chaque fois le contenu de
la base, et le déroulement du programme. Expliquez. Testez sur
machine en simulant les pannes (lesquelles ? comment ?).
- Réécrivez ce programme pour qu'il soit robuste aux pannes.
Donnez toutes les variantes possibles. Testez sur machine en
simulant les pannes.
- Considérons mieux votre programme. Est-il possible qu'un des
ordres échoue sans faire échouer la transaction ? Votre
programme est-il donc fiable ? Indiquez intuitivement ce qu'il
faudrait faire pour qu'il le devienne.5 Est-ce le même
problème pour toutes les variantes ?
©S. Abiteboul, E. Waller, B. Amann
la page du cours
2 Introduction au contrôle de concurrence
Oracle gère des verrous pour contrôler les processus
concurrents, au niveau des tables ou des n-uplets. Certains sont
posés implicitement (sur les n-uplets lors des mises à jour
d'instance), d'autres explicitement (sur les tables). Il n'est pas
possible que deux processus possèdent des verrous globaux sur la meme table
ou locaux sur le meme n-uplet. Les verrous sont relâchés en fin de
transaction.
On s'initie ci-dessous à intuiter le déroulement des ordres posant
des verrous, puis à en poser nous-même là où il faut.
2.1 Analyse de programme
On considère une table T(A,B : integer) contenant au début
les n-uplets (1,1) et (2,2).
Tout ordre dessus est autorisé à tout utilisateur.
On considère deux processus clients p1 et p2 qui effectuent les
séquences d'ordres suivantes, immédiatement après leur
connexion. Un autre client quelconque est représenté par p3.
Remplir les tableaux dans l'ordre dans lequel les ordres
sont effectivement exécutés. Puis vérifiez sur machine.
-
1 (p1) : delete t where b=1
2 (p1) : commit
client |
ordre |
T ds trans p1 |
T ds trans p2 |
T vue par p3 |
|
|
11 |
11 |
11 |
|
|
22 |
22 |
22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
1 (p1) : delete t where b=1
2 (p2) : update t set b=b-1
3 (p1) : commit
4 (p2) : commit
client |
ordre |
T ds trans p1 |
T ds trans p2 |
T vue par p3 |
|
|
11 |
11 |
11 |
|
|
22 |
22 |
22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
1 (p2) : update t set b=b-1
2 (p1) : delete t where b=1
3 (p2) : commit
4 (p1) : commit
client |
ordre |
T ds trans p1 |
T ds trans p2 |
T vue par p3 |
|
|
11 |
11 |
11 |
|
|
22 |
22 |
22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
1 (p1) : update t set a = 1 where b = 2
2 (p2) : delete t where a = 1
3 (p1) : commit
4 (p2) : commit
client |
ordre |
T ds trans p1 |
T ds trans p2 |
T vue par p3 |
|
|
22 |
22 |
22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2.2 Demandes de verrous mutuellement bloquantes
Dans chacune des questions suivantes, la table T(A integer, B integer)
contient au départ les n-uplets 1 1 et 2 2.
Conclusions ?
-
Un processus client p1 exécute, sur la table T, la
séquence d'ordres SQL suivante :
insert 1 1; delete 1 1; commit;
Décrire après chacun de ces ordres ce que voit :
-
p1
- tout autre processus différent de p1
- On considère les séquences d'ordres SQL suivantes :
s1: s2:
update T set A=A+1; update T set A=A+1;
commit; commit;
s3: s4:
update T set A=A+1; delete T where (A=2);
commit; commit;
Détailler les problèmes pouvant survenir lors de l'exécution
concurrente des séquences s1 et s2 par deux utilisateurs
différents. De même pour l'exécution concurrente des
séquences s3 et s4. Expliquer comment Oracle gère les
problèmes liés à ces accès concurrents.
- On considère maintenant les deux séquences d'ordres
SQL+ suivantes :
s5: s6:
update T set A=A+1 where (A=1); update T set A=A+1 where (A=2);
update T set A=A+1 where (A=2); update T set A=A+1 where (A=1);
commit; commit;
Détailler les problèmes liés à l'exécution concurrente
des squences s5 et s6 par des utilisateurs différents.
Quelles sont les solutions que propose Oracle pour gérer ce type de
problème.
2.3 Construction de programme
On considère la situation classique dans laquelle deux agences de
voyages accèdent concurremment à une table Reservation à
deux colonnes Nom et Num_place. Il y a 100 n-uplets, un
par place, de numéros 1 à 100. Le nom correspondant est
indéfini jusqu'à ce qu'une réservation ait lieu.
Testez tous les exercices ci-dessous sur machine.
-
Ecrivez un premier programme naïf (sans verrous explicites) qui
regarde s'il y a une place libre, la place dans une variable locale,
puis met à jour le n-uplet correspondant.
-
Montrez que votre programme n'est pas robuste à la concurrence, en
en déroulant deux exemplaires d'une manière qui réserve deux
fois la même place.
-
Posez un ou des verrous sur un seul de ces deux programmes (par
exemple il se dit qu'il va se protéger en gérant des verrous).
Montrez que votre programme n'est toujours pas robuste à la
concurrence, par un exemple analogue à celui ci-dessus...
Le contrôle de concurrence est donc une affaire à gérer à
plusieurs !
-
Réglez enfin le problème...
©S. Abiteboul, E. Waller, B. Amann
/p>