Sie sind auf Seite 1von 13

TP transactions et procédures

Conformément `a la norme SQL2, on peut définir le mode (lecture seule ou lecture écriture) d’une
transaction par l’instruction :
SET TRANSACTION { READ ONLY | READ WRITE };
Il est également possible de spécifier le niveau d’isolation d’une transaction :
SET TRANSACTION ISOLATION LEVEL { SERIALIZABLE | READ COMMITTED };
Par défaut, le mode d’une transaction est READ WRITE et son niveau d’isolation est READ
COMMITTED.
Dans la suite, nous allons déterminer expérimentalement la signification des déférents modes et
niveaux d’isolation et voir que leurs valeurs par défaut ne garantissent pas la sérialisabilité des
transactions.

Partie 1
Pour ce TP il faut ouvrir deux connexions, avec deux utilisateurs Xuser et Yuser
ayant tous les droits

Rappel : en Oracle, une instruction DDL ou DCL (create, drop, grant,…)


commence par valider la transaction précédente (commit) puis s’exécute dans une
nouvelle transaction qui se termine ensuite par un commit si l’instuction DDL s’est
bien passée, sinon la transaction ne se termine pas (ceci n’est pas le cas en
PostgreSQL).

Découvrir l’isolation en mode serializable

Pour obtenir le niveau d’isolation serializable on est obligé d’exécuter set


transaction isolation level serializable en première instruction de la transaction.

En isolation serializable une transaction T voit la base de données dans l’état


validé dans lequel elle était à son début, quoi que fasse les autres transactions, si
une instruction de T est bloquée par la modification d’une autre transaction T′,
un commit de T′ provoquera une erreur de sériabilité car la transaction tentera de
modifier une version trop ancienne, en revanche un rollback deT′ permettra à
l’instruction de faire son travail.

Dans les tableaux un couple (SCN, valeur) est une valeur de ligne et correspond à :

 SCN est le numéro de la transaction ayant produit cette valeur de la ligne,


 valeur est la valeur de la ligne.
gauche Tr. 1 create table T (x Number (5)) ; -- fin de transaction
-- une nouvelle transaction commence
-- avec la prochaine instruction
set transaction isolation level serializable ; -- SCN = 1
insert into T values (1) ;
insert into T values (2) ;
insert into T values (3) ;
select * from T ;
État 1 table T segment de recouvrement
SCN (valeur) SCN (valeur) SCN (valeur) SCN (valeur)
Transactions 1 (1) aucune ancienne version
actives : 1 (2) aucune ancienne version
(1) 1 (3) aucune ancienne version

Remarquez qu’une ligne dont toutes les versions sont en gras est
verrouillée. C’est le cas des lignes qui viennent d’être insérées, la transaction
possédant le verrou est soulignée.

droite Tr. 2 set transaction isolation level serializable ; -- SCN = 2


select * from T ;

Q.1 Pourquoi droite voit-elle la table vide ?

Il faut que gauche publie ses insertions :

gauche Tr. 1 commit ; -- fin de transaction SCN = 1


droite Tr. 2 select * from T ;

Q.2 Pourquoi droite voit-elle toujours la table vide ?

droite Tr. 2 commit ; -- fin de transaction SCN = 2

Il faut que droite commence une nouvelle transaction :

droite Tr. 3 set transaction isolation level serializable ; -- SCN = 3


select * from T ;

Q.3 Pourquoi droite voit-elle enfin le contenu de T ?

Effet du rollback

droite Tr. 3 update T set x = 22 where x = 2 ;


select * from T ;
État 2 table T segment de recouvrement
SCN (valeur) SCN (valeur) SCN (valeur) SCN (valeur)
Transactions 1 (1)
actives : 3 (22) 1 (2)
(3) 1 (3)
droite Tr. 3 rollback ; -- fin de transaction SCN = 3
État 3 table T segment de recouvrement
SCN (valeur) SCN (valeur) SCN (valeur) SCN (valeur)
Transactions 1 (1)
actives : 1 (2)
(4) 1 (3)
droite Tr. 4 -- une nouvelle transaction commence
-- avec la prochaine instruction
set transaction isolation level serializable ; -- SCN = 4
select * from T ;

Q.4 Pourquoi droite voit-elle l’ancien contenu de T ?

droite Tr. 4 update T set x = 22 where x = 2 ;


select * from T ;
État 4 table T segment de recouvrement
SCN (valeur) SCN (valeur) SCN (valeur) SCN (valeur)
Transactions 1 (1)
actives : 4 (22) 1 (2)
(4) 1 (3)
gauche Tr. 5 set transaction isolation level serializable ; -- SCN = 5
select * from T ;
update T set x = 222 where x = 2 ;
État 5 table T segment de recouvrement
SCN (valeur) SCN (valeur) SCN (valeur) SCN (valeur)
Transactions 1 (1)
actives : 4 (22) 1 (2)
(4, 5) 1 (3)

Q.5 Pourquoi gauche voit-elle l’ancien contenu de T ?

Q.6 Pourquoi le update de gauche est-il bloqué ?

droite Tr. 4 commit ; -- fin de transaction SCN = 4


État 6 table T segment de recouvrement
SCN (valeur) SCN (valeur) SCN (valeur) SCN (valeur)
Transactions 1 (1)
actives : 4 (22) 1 (2)
(5) 1 (3)

Q.7 Pourquoi le update de gauche se débloque-t-il avec une erreur de sériabilité ?

gauche Tr. 5 rollback ; -- fin de transaction SCN = 5


État 7 table T segment de recouvrement
SCN (valeur) SCN (valeur) SCN (valeur) SCN (valeur)
Transactions 1 (1)
actives : 4 (22) 1 (2)
() 1 (3)
gauche Tr. 6 set transaction isolation level serializable ; -- SCN = 6
droite Tr. 7 set transaction isolation level serializable ; -- SCN = 7
update T set x = 333 where x = 22 ;
select * from T ;
État 8 table T segment de recouvrement
SCN (valeur) SCN (valeur) SCN (valeur) SCN (valeur)
Transactions 1 (1)
actives : 7 (333) 4 (22) 1 (2)
(6, 7) 1 (3)
gauche Tr. 6 update T set x = 25 where x = 22 ;

Q.8 Pourquoi gauche est-elle bloquée ?

droite Tr. 7 rollback ; -- fin de transaction SCN = 7


État 9 table T segment de recouvrement
SCN (valeur) SCN (valeur) SCN (valeur) SCN (valeur)
Transactions 1 (1)
actives : 4 (22) 1 (2)
(6) 1 (3)

Q.9 Pourquoi le update de gauche réussit-il ?

gauche Tr. 6 commit ; -- fin de transaction SCN = 6


État 10 table T segment de recouvrement
SCN (valeur) SCN (valeur) SCN (valeur) SCN (valeur)
Transactions 1 (1)
actives : 6 (25) 4 (22) 1 (2)
() 1 (3)
droite Tr. 8 set transaction isolation level serializable ; -- SCN = 8
select * from T ;

Q.10 Pourquoi droite voit-elle la version la plus récente de T ?

Et maintenant un interblocage.

droit update T set x = 11 where x = 1 ;


e Tr. select * from T ;
8
État table T segment de recouvrement
11 SCN (valeur) SCN (valeur) SCN (valeur) SCN (valeur)
Transactions 8 (11) 1 (1)
actives : 6 (25) 4 (22) 1 (2)
(8) 1 (3)
gauche Tr. 9 set transaction isolation level serializable ;
-- SCN = 9
update T set x = 33 where x = 3 ;
select * from T ;
update T set x = 111 where x = 1 ;
État 12 table T segment de recouvrement
SCN SCN SCN SCN
(valeur) (valeur) (valeur) (valeur)
Transactio
8 (11) 1 (1)
ns
actives : 6 (25) 4 (22) 1 (2)
(8, 9) 9 (33) 1 (3)

Q.11 Pourquoi gauche est-elle bloquée ?

droite Tr. 8 update T set x = 333 where x = 3 ;

Q.12 Quelle est la transaction dont l’instruction a échoué par interblocage, et celle
dont l’instruction est toujours bloquée ? Faites un rollback de la transaction dont
l’instruction a échoué.

État 13 table T segment de recouvrement


SCN (valeur) SCN (valeur) SCN (valeur) SCN (valeur)
Transactions 8 (11) 1 (1)
actives : 6 (25) 4 (22) 1 (2)
(8) 1 (3)

Q.13 Voit-on alors l’effet du verrouillage deux phases rigoureux ? Faites


un commit de la transaction ayant réussi.

État 14 table T segment de recouvrement


SCN (valeur) SCN (valeur) SCN (valeur) SCN (valeur)
Transactions 8 (11) 1 (1)
actives : 6 (25) 4 (22) 1 (2)
() 8 (333) 1 (3)

Suppression de ligne
droi set transaction isolation level serializable ; -- SCN = 10
te delete from T where x = 25 ;
select * from T ;
Tr.
10
État table T segment de recouvrement
15 SCN (valeur) SCN (valeur) SCN (valeur) SCN (valeur)
Transactions 8 (11) 1 (1)
actives : 10 (+) 6 (25) 4 (22) 1 (2)
(10) 8 (333) 1 (3)
gauche Tr. 11 set transaction isolation level serializable ;
-- SCN = 11
insert into T values (421) ;
select * from T ;
update T set x = 255 where x = 25 ;
État 16 table T segment de recouvrement
SCN SCN SCN SCN
(valeur) (valeur) (valeur) (valeur)
Transacti
8 (11) 1 (1)
ons
actives : 10 (+) 6 (25) 4 (22) 1 (2)
(10, 11) 8 (333) 1 (3)
11 (421)

Q.14 Que voit gauche ?

Q.15 Pourquoi gauche est-elle bloquée lors du update ?

droite Tr. 10 commit ; -- fin de transaction SCN = 10


État 17 table T segment de recouvrement
SCN (valeur) SCN (valeur) SCN (valeur) SCN (valeur)
Transactions 8 (11) 1 (1)
actives : 10 (+) 6 (25) 4 (22) 1 (2)
(11) 8 (333) 1 (3)
11 (421)

Q.16 Qu’arrive-t-il à gauche et combien de lignes sont modifiées par son update ?
Et pourquoi la ligne détruite est-elle toujours là ?

gauche Tr. 11 select * from T ;


commit ; -- fin de transaction SCN = 11
gauche Tr. 12 set transaction isolation level serializable ; -- SCN = 12
select * from T ;
État 18 table T segment de recouvrement
SCN (valeur) SCN (valeur) SCN (valeur) SCN (valeur)
Transactions 8 (11) 1 (1)
actives : 8 (333) 1 (3)
(12) 11 (421)

Partie 2
il faut alors ouvrir deux connexions. Les manipulations qui suivent utiliseront une table T ayant 2
colonnes numériques A et B. On utilisera les abréviations suivantes :
– select T pour select * from T ;
– T(A=1) pour select * from T where A=1 ;
– insert (3,6) pour insert into T values (3,6) ;
– update(A<-A+1) pour update T set A=A+1 ;
– update(A<-3)|(A=4) pour update T set A=3 where A=4 ;
– delete(A=4) pour delete from T where A=4.
Commencez par créer la table T ayant 2 colonnes num´eriques A et B.
Avec Oracle, il existe une clause for update `a l’instruction select. L’expérience suivante va vous
permettre de comprendre son utilité

.
Partie 3
Script de la base
- Description : Création des tables pour la base "Bibliothèque"
--
-- +----------------------------------------------------------------------------------------------------------------+
-- | Création utilisateur, autorisations, connexion |
-- +----------------------------------------------------------------------------------------------------------------+

-- +----------------------------------------------------------------------------------------------------------------+
-- | Destruction des tables 'lecteur', 'livre' |
-- +----------------------------------------------------------------------------------------------------------------+

drop sequence num_livre_seq;


drop sequence num_lecteur_seq;

-- Attention a l'ordre dans lequel les drop sont effectues. Il faut que les tables
-- contenant des cles etrangeres sur d'autres tables soient dropees avant celles-ci
drop table livre;
drop table lecteur;

drop view infos_livre;


drop view infos;

drop procedure inserer_livre;


drop procedure supprimer_livre;
drop procedure inserer_lecteur;
drop procedure emprunter;
drop procedure rendre;

-- +----------------------------------------------------------------------------------------------------------------+
-- | Création des tables 'lecteur', 'livre' |
-- +----------------------------------------------------------------------------------------------------------------+
create sequence num_livre_seq;
create sequence num_lecteur_seq;

create table lecteur


(
num_lecteur number,
nom varchar2(10),
constraint pk_lecteur primary key(num_lecteur)
);
show error

create table livre


(
num_livre number,
nom varchar2(60),
titre varchar2(30),
collection varchar2(30),
coll_id number not null,
lecteur_id number,
constraint pk_livre primary key(num_livre),
constraint fk_emprunt foreign key(lecteur_id) references lecteur
);
show error

create view infos_livre (num_livre,titre,auteur,collection,lecteur) as


(select num_livre,titre,livre.nom,collection, lecteur.nom
from livre,lecteur
where lecteur_id=num_lecteur);
show error

create view infos(num_livre,lecteur_id) as


(select num_livre,lecteur_id from livre);
show error

-- +----------------------------------------------------------------------------------------------------------------+
-- | Création des procédures PLSQL d'insertion dans les tables |
-- +----------------------------------------------------------------------------------------------------------------+

create or replace procedure inserer_livre(


nom varchar2,
titre varchar2,
collection varchar2,
ref varchar2)
is
begin
insert into livre values
(
num_livre_seq.nextval,
nom,
titre,
collection,
ref,
NULL
);
end;
/
show error

create or replace procedure supprimer_livre(numlivre integer) is


begin
delete from livre where num_livre=numlivre;
end;
/
show error

create or replace procedure inserer_lecteur(nom varchar2) is


begin
insert into lecteur values (num_lecteur_seq.nextval,nom);
end;
/
show error

create or replace procedure emprunter(


numlivre integer,
numlecteur integer)
is
begin
update livre
set lecteur_id = numlecteur
where num_livre=numlivre and lecteur_id is null;
end;
/
show error

create or replace procedure rendre(


numlivre integer)
is
begin
update livre
set lecteur_id = NULL
where num_livre=numlivre;
end;
/
show error

-- +----------------------------------------------------------------------------------------------------------------+
-- | Insertion de données |
-- +----------------------------------------------------------------------------------------------------------------+

exec inserer_lecteur('Picouet');
exec inserer_lecteur('Tanguy');
exec inserer_lecteur('Segarra');

exec inserer_livre('Kundera','Risibles amours', 'Folio', '1702');


exec inserer_livre('Kessel','La vallée des rubis','Folio','2560');
exec inserer_livre('Kundera','L''immortalité','Folio','2447');
exec inserer_livre('Léo Malet','Nestor Burma court la poupée','10-18','2110');
exec inserer_livre('Dos Passos','Aventures d''un jeune homme','Folio','1808');
exec inserer_livre('Kundera','Risibles amours', 'Folio', '1702');
exec inserer_livre('Kundera','Risibles amours', 'Folio', '1702');

exec emprunter (1, 2);


exec emprunter (2, 1);
exec emprunter (3, 2);
exec emprunter (4, 3);
exec emprunter (5, 3);

commit;

-- +----------------------------------------------------------------------------------------------------------------+
-- | SALUT ! |
-- +----------------------------------------------------------------------------------------------------------------+

grant select, insert on livre to public;


grant select, update, insert, delete on lecteur to public;
grant select on infos_livre to public;
grant execute on inserer_livre to public;
grant execute on inserer_lecteur to public;
grant execute on emprunter to public;

grant execute on rendre to public;


commit;

LES TABLES
La table Livre contient des informations sur les différents livres de la bibliothèque, ainsi que la référence du
lecteur qui l’a emprunté. La table Lecteur contient des informations sur les lecteurs inscrits à la bibliothèque.
Pour voir le contenu de ces deux tables, tapez la commande suivante dans l’interpréteur SQL (attention à ne
pas oublier le « ; » à la fin de la commande) : select * from nom_table ;
Pour voir la structure de ces deux tables tapez la commande : desc nom_table ;
B. LES VUES
Les vues vous permettent d’accéder plus simplement à certaines informations. Pour interroger une vue utiliser
la commander : select * from nom_vue
Vous avez à votre disposition deux vues :
infos : affichant les numéros de livre et les numéros de leurs emprunteurs
infos_livre : affichant toutes les informations détaillées sur les livres

Pour observer la structure des vues, utilisez les mêmes commandes que pour les tables.
C. LES PROCEDURES STOCKEES
Les procédures stockées permettent d’effectuer des requêtes prédéfinies lors de la création de la base. Pour
effectuer ce TP un certain nombre de procédures vous sont fournies, prenez le temps tout au long des
exercices de les lire. Pour exécuter une procédure stockée utilisez la commande suivante :
exec nom_procedure(attribut1, … , attributn)
Vous disposez des procédures stockées suivantes (lors de l’appel n’indiquez pas le typage !) :
varchar nom , varchar titre ,varchar collection, int ref)
int numlivre)
varchar nom)
int numlivre, int numlecteur)
int numlivre)

Ouvrez le fichier de script de création de la base de données afin de lire le code des procédures lorsque vous
les utilisez lors de cet exercice.
Ouvrez deux sessions afin d’accéder à votre base de données en simulant plusieurs utilisateurs.
1. VALIDATION D’UNE TRANSACTION
1. Dans la session A, observez l’état des relations en utilisant la vue infos. Ajoutez ensuite un nouveau
lecteur et un nouvel emprunt à la base en utilisant les procédures stockées inserer_lecteur et emprunter.
2. Interrogez les relations dans la session B en utilisant la vue infos. Que constatez-vous ?
3. Dans la session A, validez la mise à jour avec la commande « commit ; ».
4. Que constatez-vous dans la session B ?
5. Pour rétablir l’état d’origine, rendre le livre emprunté dans la session A, validez avec la commande «
commit ; »

2. RETOUR A L’ETAT D’ORIGINE


1. Dans la session A, ajoutez un nouveau lecteur.
2. Est-il présent dans la session B ?
3. Dans la session A, exécutez la commande « rollback ; » puis la commande « commit ; »
4. Que constatez-vous dans chacune des sessions ?

3. DEUX EMPRUNTS SIMULTANES


1. Dans la session A, le lecteur n°1 emprunte le livre n°6 tandis que dans la session B, le lecteur n°2
emprunte le même livre. Que constatez-vous ?
2. Effectuez un commit dans la session A.
3. Interrogez les relations depuis les deux sessions. Que constatez-vous ?
4. Effectuez un commit dans la session B. Que constatez-vous ?

4. SUPPRESSION D’UN LIVRE EN COURS D’EMPRUNT


1. Dans la session A, le lecteur n°3 emprunte le livre n°7 tandis que dans la session B le livre n°7 est
supprimé au moyen de la procédure supprimer_livre. Que constatez-vous ?
2. Effectuez un commit dans la session A puis interrogez les relations depuis les deux sessions. Que
constatez-vous ?
3. Effectuez un commit dans la session B puis interrogez les relations depuis les deux sessions. Que
constatez-vous ?

Das könnte Ihnen auch gefallen