Dept Informatique Licence Pro 2015/2016 TP Transactions et CC
Transcription
Dept Informatique Licence Pro 2015/2016 TP Transactions et CC
Dept TP Transactions et adaptation du TP de R. Charrier et G. Licence Pro 2015/2016 Simon Informatique CC <<<<< Transactions Oracle : comprendre le fonctionnement d'une transaction >>>>> • Objectifs • - comprendre ce qu'est une transaction • - manipuler des transactions • - se rendre compte des problèmes posés (interblocages, ...) • Préalable On suppose que la base contenant les tables EMP et DEPT est installée sous Oracle. • Définitions • Définition 1 : Une transaction est un ensemble de requêtes et d'actions qui permet de faire passer la base de données d'un état cohérent dans un autre état cohérent. • Définition 2 : Du point de vue de l'utilisateur réalisant une transaction, il est souhaitable que les différentes opérations de la transaction apparaissent comme une opération unique (donc que les différentes opérations apparaissent comme étant exécutées simultanément) => ATOMICITE, c-a-d qu'Une séquence d'instructions possédant cette propriété est dite atomique. On simule l'exécution concurrente de deux transactions en exécutant SQLPLUS dans deux terminaux différets : xterm1 et xterm2. Sous SQLPLUS : faire SET AUTOCOMMIT ON Question 1.1. : connexions multiples sans transaction explicite (comportement pas défaut) Dans le xterm1, taper la commande qui insère un nouvel employé (un nouveau tuple dans la table EMP). Dans chacun des deux xterms, afficher le nom et le job des employés. Que constatez-vous et pourquoi ? Sous SQLPLUS : faire SET AUTOCOMMIT OFF Question 1.2. dans xterm1, mettre à jour un tuple de la table EMP , et visualiser le résultat (les attributs ename et job seulement) : Question 1.3. dans xterm2, afficher maintenant les attributs ename et job de la table EMP : Que remarque-t-on et pourquoi ? Question 2 : Validation de transaction par commit Crée une table employees_temp comme emp empno, ename, job) Insérer un nouveau tuple dans cette table et afficher la table. Taper le code PL/SQL suivant (c'est une transaction) BEGIN UPDATE employees_temp SET ename = 'MARC' WHERE empno = 267; END; / Dans xterm1, afficher la table employees_temp. Dans xterm2, afficher la table employees_temp. Que constatez-vous et pourquoi? Dans xterm1, faire COMMIT; Afficher la table employees_temp. Que remarque-t-on ? Conclusion ? Question 3 : Annulation de transaction par rollback Faire set autocommit ON Recommencer le même scénario que dans la question 2 mais en remplaçant COMMIT par ROLLBACK à l'étape 3, c-à-d Insérer un nouveau tuple dans la table employees_temp, et le visualiser dans xterm1, puis dans xterm2 (afficher la table employees_temp). Que constatez-vous et pourquoi ? Dans xterm1, faire ROLLBACK; Dans xterm1 et xterm2, afficher la table employees_temp. Que remarquerz-vous et pourquoi ? Question 4 : Ensemble de mises-à-jour cohérentes Creer une relation ECOLE (ecoleno, ecolenom, nbenseignants) où clé = ecoleno Creer une relation ENSEIGNE (empno, ecoleno, nbheures), clé = (empno, ecoleno) Inserer 5 tuples dans chaque table (en coherence avec la table EMP) Si un nouvel enseignement est inséré (exemple : l'employe 3902 a enseigne 15 heures dans l'ecole 100)), il faudra faire deux actions : 1) insérer cet enseignement dans la table enseigne. 2) incrémenter le nombre d'heures enseignées dans l'ecole concernee. Pour une raison de cohérence des données, on ne peut pas faire la première action sans être certain que la deuxième action sera faite ! Les deux requêtes SQL doivent donc être considérées par le SGBD comme une seule opération (atomicité d'une transaction). Pour ce faire, on utilise donc une transaction. Question 4.1 : écrire la transaction permettant de réaliser un nouvel enseignement (prendre un exemple cohérent avec vos données). Dans xterm1 : set autocommit off Begin insert into enseigne values (7934, 1004, 10); update ecole set NBENSEGNANTS = NBENSEGNANTS+1 where ecoleno = 1004; end; / PL/SQL procedure successfully completed. SQL> select * from ecole; ECOLENO ECOLENOM NBENSEGNANTS ---------- -------------------- -----------1001 ecole1 52 1002 ecole2 61 1003 ecole3 71 1004 ecole4 81 SQL> Dans xterm2 : QL> select * from ecole; ECOLENO ECOLENOM NBENSEGNANTS ---------- -------------------- -----------1001 ecole1 52 1002 ecole2 53 1003 ecole3 54 1004 ecole4 55 ==> modifs non visibles Dans xterm1 : COMMIT ; Dans xterm2 : SQL> select * from ecole; ECOLENO ECOLENOM NBENSEGNANTS ---------- -------------------- -----------1001 ecole1 52 1002 ecole2 61 1003 ecole3 71 1004 ecole4 81 SQL> => Remarque ? Question 4.2 : tant que le commit n'a pas été fait, quelle est le nombre d'heures enseignées dans l'école vu par les autres utilisateurs ? On va de nouveau travailler avec deux connexions dans deux xterms différents. Mais on va cette fois manipuler deux transactions en parallèle. Question 5 : Transactions concurrentes – insert+select TR1 TR2 begin insert into emp (empno, ename)values (1200, 'black'); select * from emp; begin on attend .. on attend … select * from emp; end; / select empno, ename from emp; commit; select * from emp ; Que constatez-vous ? Question 6 : Transactions concurrentes - 2 update sur le même tuple xterm1 xterm2 begin Begin update dept set loc = 'HAVRE' where deptno = 20; end; / PL/SQL procedure successfully completed. SQL> select * from dept; update dept set loc = 'ROUEN' where deptno = 20; end; / / /* trans2 bloquée, car tuplee vérrouillée par trans1 */ COMMIT ; PL/SQL procedure successfully completed. SQL> /* trans1 a validé (COMMIT) donc trans peut poursuivre avec la mise à jour du même tuple */ select * from dept; SQL> select * from dept; DEPTNO DNAME LOC ---------- -------------- ------------10 ACCOUNTING NEW YORK 20 RESEARCH PARIS 30 SALES CHICAGO 40 OPERATIONS BOSTON SQL> => modif de trans2 non visible dans xterm1…………………….mais visible dans xterm2 …………………………………………………………………...SQL> select * from dept; DEPTNO DNAME LOC ---------- -------------- ------------10 ACCOUNTING NEW YORK 20 RESEARCH ROUEN 30 SALES CHICAGO 40 OPERATIONS BOSTON SQL> Que constatez-vous dans xterm1 ? Question 7 : Transactions concurrentes - Etreinte fatale (interblocage) xterm1 : SQL> begin 2 update dept set loc = 'toulouse' where deptno=10; 3 end; 4 / PL/SQL procedure successfully completed SQL> xterm2 : SQL> begin 2 update dept set loc='bordeaux' where deptno=30; 3 end; 4 / PL/SQL procedure successfully completed. SQL> xterm1 : SQL> begin 2 update dept set loc='bordeaux' where deptno=30; 3 end; 4 / => ?? xterm2 : SQL> begin 2 update dept set loc='marseille' where deptno=10; 3 end; 4 / => ?? ⇒ problèle de ??? => Débloquer :