Nom : Prénom : page 1 Transactions Université Pierre et Marie Curie - Paris 6 - UFR 919 - Licence d'informatique LI345 - EXAMEN DU 4 JUIN 2010 Durée : 2h ---documents autorisés On note Li(X) : lecture de X par la transaction Ti, Ei(X) : écriture de X par la transaction Ti, Vi : validation de la transaction Ti. On considère les deux exécutions suivantes : 1. E2(A), E1(B), L3(A), E2(B), E1(C), L2(C), E1(A), V1, V2, V3 2. E1(A), E2(B), E3(C), L1(B), E1(C), L3(A), V1, V2, V3 Question 1. Ces deux exécutions provoquent-elles un interblocage, si on considère un SGBD utilisant du verrouillage deux phases strict (les verrous d une transaction sont relâchés au moment de la validation)? Justifiez vos réponses (la justification compte pour la moitié des points) Exécution 1 : 3pts Exécution 2 : 1 : T3 attend T2 (A), T2 attend T1( B et C), T1 attend T3 (A). Il y a blocage 2. T1 attend T2 (B), T1 attend T3 (C), T3 attend T1 sur A. Il y a blocage. Question 2. Ces deux exécutions provoquent-elle un interblocage si on considère un SGBD dans lequel le contrôle de concurrence se fait par clichés multi-version? Justifiez vos réponses. Exécution 1 : Exécution 2 : Avec le cliché multi version, il n y a pas de verrous pour la lecture. Exécution 1 : T2 attend T1(B), T1 attend T2(A), il y a interblocage ; Exécution 2 : T1 attend T3 (C ) pas d interblocage. Question 3. On considère les instructions suivantes : a) set A=A+1 b) set B=B+2 c) set A=A+B d) set B=10 Une instruction traitée par une transaction Ti est désignée par la lettre de l instruction suivie du numéro i de la transaction. Par exemple, a1 représente l instruction a traitée par la transaction T1. Les séquences suivantes produisent-elles un interblocage? 1. T1a, T2b, T1c, T2d 2. T1C, T2a, T2d, T1b
Lettres initiales du Prénom et du Nom: page 2 Exécution 1 : Exécution 2 : Pas d interblocage pour 1 T2 attend T1 sur A et sur B, mais T1 peut conclure et libérer les verrous. Pas d interblocage pour 2, car T2 attend T1, mais T1 ayant les deux verrous, peut continuer. SQL3 : Modélisation 2 Pts On veut définir en SQL3 le schéma d une base de données touristique. On veut définir un type Ville, qui a un nom, des restaurants et des musées. Un restaurant a un nom, une adresse et une liste de 3 menus. Les types Musée et Menu sont définis de la manière suivante : Create type Musee as object( Nom varchar(20), JourFermeture varchar(15) ) ; Create type Menu as object ( Nom varchar (20), Prix Number (2) ) ; Question 1. Définir le type Restaurant Create type LesMenus as varray (3) of Menu ; Create type Restaurant as object ( Nom varchar (20), Adresse varchar (50), Menus LesMenus ) ; On peut aussi définir un type adresse contenant une rue un numéro et une ville. Question 2. Définir le type Ville
Lettres initiales du Prénom et du Nom: page 3 Create type EnsRestos as table of Restaurant ; Create type EnsMusees as table of Musee; Create type Ville as object ( Nom Varchar (25), Resto EnsRestos, LesMusees EnsMusees ); Question 3. Définir la table permettant de stocker toutes ces données. Create table LesVilles of Ville Nested table Resto stored as lesrestaurants, Nested table LesMusees stored as touslesmusees; Pas de nested table pour lesmenus car c est un varray. Mais si c est déclaré comme une table, il faut la nested table. On mettra des Ref dans les types EnsRestos, EnsPusees, et LesMenus que s il y a des tables les stockant. SQL3 : Mise à jour et interrogation On considère le schéma relationnel objet suivant : CREATE TYPE Personne as object( Nom Varchar2(20), Sexe Varchar2(1), Age Number(2)) ; CREATE TYPE EnsPersonnes as table of Ref Personne; CREATE TYPE Visite AS OBJECT ( Nom varchar2(20), Duree Number(2)); CREATE TYPE EnsVisites as table of Visite ; CREATE TYPE Destination as object ( Pays varchar2(20), Lieux EnsVisites); CREATE TYPE Tour as object ( Identifiant Varchar2 (20), 4 Pts
Lettres initiales du Prénom et du Nom: page 4 Programme Destination, Inscrits EnsPersonnes); CREATE TABLE LesTours OF Tour NESTED TABLE inscrits STORE AS tabinscrits, NESTED TABLE programme.lieux STORE AS tablieux ; CREATE TABLE LesPersonnes OF Personne; INSERT INTO LesPersonnes values Personne( Robinson, M, 32) ; Question.1 Donner l instruction permettant d insérer le tour Toscane2010, qui a pour destination l Italie, et qui comporte une visite à Florence pour une durée de 3 jours, et une à Pise pour une durée de 2 jours. INSERT INTO LesTours VALUES Tour ( Toscane2010, Destination ( Italie, EnsVisites (Visite( Florence, 3), Visite( Pise, 2))), EnsPersonne()) ; Question 2. Donner l instruction inscrivant la personne s appelant Robinson au tour Toscane2010. Avec insert : Insert into table((select t.inscrits from LesTours t where t.identifiant= Toscane2010 )) values ((select ref(p) from LesPersonnes p where p.nom= Robinson )); Avec update (il faut avoir mis EnsP() et pas NULL dans la première insertion. UPDATE LesTours t SET t.inscrits=enspersonnes((select REF(p) from LesPersonnes p where p.nom= Robinson )) WHERE t.identifiant= Toscane2010 ; Question 3 Donner l expression en SQL3 des requêtes suivantes : 1. Personnes voyageant en Italie et visitant Pise
Lettres initiales du Prénom et du Nom: page 5 SELECT value(p), FROM LesTours t, table (t.inscrits) p, table (t.programme.lieux) l WHERE t.programme.pays = Italie and l.nom= Pise ; 2. Quels sont les lieux touristiques en Italie où il est prévu une visite de plus de 2 jours? SELECT value(l) FROM LesTours t, table(t.programme.lieux) l Where t.programme.pays= Italie and l.duree > 2 XML-DTD-XSLT 6 pts L entreprise Leepsis déménage. Chaque employé de cette entreprise a un numéro d ancien bureau et un numéro de nouveau bureau. Par exemple, l employé Dupont a pour ancien bureau le numéro K126 et pour nouveau bureau le numéro J32. Si deux employés sont dans le même nouveau bureau alors on dit qu ils sont collègues de bureau. Les informations du déménagement sont stockées dans un document XML. Chaque employé a un identifiant et un nom, ainsi qu éventuellement un numéro d ancien bureau, un numéro de nouveau bureau, ainsi que des meubles. Si un employé partage le bureau avec un collègue alors, pour éviter de stocker inutilement de l information, il n y a qu un seul des deux employés qui possède le numéro du nouveau bureau. Par exemple, dans le document XML Leepsis.xml ci-après, l employé Wang et l employé Martin sont collègues de bureau (ils possèdent tous les deux un attribut collegue faisant référence à la personne avec laquelle ils partageront le nouveau bureau), mais l employé Martin ne contient pas le numéro du nouveau bureau. Voici le fichier Leepsis.xml qui contient les informations du déménagement de l entreprise Leepsis. <?xml version="1.0"?> <!DOCTYPE demenagement SYSTEM "demenagement.dtd"> <demenagement> <personne id='p1'> <nom>dupont</nom> <ancienb>k126</ancienb> <nouveaub>j32</nouveaub> <meuble>armoire</meuble> <meuble>chaise</meuble> </personne> <personne id='p2' collegue='p3'> <nom>wang</nom>
Lettres initiales du Prénom et du Nom: page 6 <ancienb>k325</ancienb> <nouveaub>j18</nouveaub> <meuble>armoire</meuble> </personne> <personne id='p3' collegue='p2'> <nom>martin</nom> <ancienb>k229</ancienb> <meuble>lampe</meuble> </personne> </demenagement> 1. Compléter la DTD demenagement.dtd ci-après pour qu elle respecte les contraintes données dans l énoncé et qu elle valide le document Leepsis.xml <!ELEMENT demenagement...> <!ELEMENT personne...> <!ATTLIST personne...> <!ELEMENT nom...> <!ELEMENT ancienb...> <!ELEMENT nouveaub...> <!ELEMENT meuble...> <!ELEMENT demenagement (personne)* > <!ELEMENT personne (nom,ancienb?,nouveaub?,meuble*) > <!ATTLIST personne id ID #REQUIRED collegue IDREF #IMPLIED> <!ELEMENT nom (#PCDATA) > <!ELEMENT ancienb (#PCDATA) > <!ELEMENT nouveaub (#PCDATA) > <!ELEMENT meuble (#PCDATA) > 2. Compléter la feuille XSL suivante pour qu elle transforme un document XML (qui suit la DTD demenagement.dtd) en un autre document XML qui suit la même DTD, mais qui contient seulement les personnes qui ont dans leurs meubles une armoire. Remarque : on ne s inquiétera pas du fait que certains collègues de bureau ne sont éventuellement plus présents dans le document. <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="1.0"> <xsl:template match="...">
Lettres initiales du Prénom et du Nom: page 7 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="1.0"> <xsl:output method="html" indent="yes"/> <xsl:template match= "/"> <demenagement> <xsl:copy-of select='//personne[meuble="armoire"]'/> </demenagement> ATTENTION : le résultat attendu est celui ci-dessous, on ne tiendra pas compte du fait que collegue référence la personne p3 qui n existe plus dans le document. <demenagement> <personne id='p1'> <nom>dupont</nom> <ancienb>k126</ancienb> <nouveaub>j32</nouveaub> <meuble>armoire</meuble> <meuble>chaise</meuble> </personne> <personne id='p2' collegue='p3'> <nom>wang</nom> <ancienb>k325</ancienb> <nouveaub>j18</nouveaub> <meuble>armoire</meuble> </personne> </demenagement> 3. Compléter la feuille XSL suivante pour qu elle transforme un document XML (qui suit la DTD demenagement.dtd) en un document HTML qui affiche le nombre de personnes qui déménagent ainsi que le nombre de meubles à déménager, et en particulier le nombre d armoires. Par exemple, pour le document Leepsis.xml, le résultat attendu est : <HTML> <p>nombre de personnes : 3</p> <p>nombre de meubles : 4, dont 2 armoires</p> </HTML> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="1.0"> <xsl:template match= "/">
Lettres initiales du Prénom et du Nom: page 8 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="1.0"> <xsl:output method="html" indent="yes"/> <xsl:template match= "/"> <HTML> <p>nombre de personnes : <xsl:value-of select='count(//personne)'/></p> <p>nombre de meubles : <xsl:value-of select='count(//meuble)'/>, dont <xsl:value-of select='count(//meuble[text()="armoire"])'/> armoires</p> </HTML> 4. Compléter la feuille XSL suivante pour qu elle transforme un document XML (qui suit la DTD demenagement.dtd) en un document HTML qui affiche un tableau HTML associant le nom d une personne et la liste de ces meubles. Par exemple, pour le document Leepsis.xml, le résultat attendu est : <HTML> <H1>Liste des personnes et leurs meubles</h1> <TABLE> </TABLE> </HTML> <TR><TH>Nom</TH><TH>Meubles</TH></TR> <TR><TD>Dupont</TD><TD> armoire chaise </TD></TR> <TR><TD>Wang</TD><TD> armoire </TD></TR> <TR><TD>Martin</TD><TD> lampe </TD></TR> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="1.0"> <xsl:template match= "..."> <xsl:template match="...">
Lettres initiales du Prénom et du Nom: page 9 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="1.0"> <xsl:output method="html" indent="yes"/> <xsl:template match= "/"> <HTML> <H1>Liste des personnes et leurs meubles</h1> <TABLE> <TR><TH>Nom</TH><TH>Meubles</TH></TR> <xsl:apply-templates select='//personne'/> </TABLE> </HTML> <xsl:template match= "personne"> <TR> <TD><xsl:value-of select='nom'/></td> <TD> <xsl:text> </xsl:text> <xsl:for-each select='meuble'> <xsl:value-of select='.'/> <xsl:text> </xsl:text> </xsl:for-each> </TD> </TR> 5. Complétez la feuille XSL suivante pour qu elle transforme un document XML (qui suit la DTD demenagement.dtd) en un document XML contenant la liste des nouveaux bureaux et pour chaque bureau la liste des noms des personnes dans ce bureau. Par exemple, pour le document Leepsis.xml, le document obtenu est : <?xml version="1.0" encoding="utf-8"?> <bureaux> <bureau id="j32"> </bureau> <personne>dupont</personne> <bureau id="j18"> </bureau> </bureaux> <personne>wang</personne> <personne>martin</personne> Afin d obtenir ce résultat, vous pourrez vous aider de l élément xsl:variable qui permet de déclarer une variable. Sa syntaxe est : <xsl:variable name='nom' select='expression'/> où nom est le nom de la variable et expression est sa valeur. Pour utiliser cette variable dans une expression Xpath, il suffit d ajouter un $ devant le nom de la variable. Pour vous aider, les deux premiers templates de la feuille de style suivante ont déjà été complétés. En particulier, un exemple d utilisation de xsl:variable est donné. Complétez le troisième template. <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="1.0">
Lettres initiales du Prénom et du Nom: page 10 <xsl:template match= "/"> <bureaux> <xsl:apply-templates select='//nouveaub'/> </bureaux> <xsl:template match= "nouveaub"> <xsl:variable name='numerob' select='text()'/> <bureau> <xsl:attribute name='id'> <xsl:value-of select="$numerob"/> </xsl:attribute> <xsl:apply-templates select="//personne[nouveaub=$numerob]"/> </bureau> <xsl:template match= "personne"> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="1.0"> <xsl:output method="xml" indent="yes"/> <xsl:template match= "/"> <bureaux> <xsl:apply-templates select='//nouveaub'/> </bureaux> <xsl:template match= "nouveaub"> <xsl:variable name='numerob' select='text()'/> <bureau> <xsl:attribute name='id'> <xsl:value-of select="$numerob"/> </xsl:attribute> <xsl:apply-templates select="//personne[nouveaub=$numerob]"/> </bureau> <xsl:template match= "personne"> <personne><xsl:value-of select='nom'/></personne> <xsl:if test='@collegue'> <xsl:variable name='idcollegue' select='@collegue'/> <personne> <xsl:value-of select='//personne[@id=$idcollegue]/nom'/>
Lettres initiales du Prénom et du Nom: page 11 </personne> </xsl:if> PHP 5 Pts On considère un réseau social, dont les informations sont stockées dans la base RéseauSocial, contenant plusieurs tables, parmi lesquelles les tables suivantes (les clés des tables sont soulignées): Utilisateur(idu, nom, profil): informations sur les membres idu: identifiant unique de l'utilisateur nom: nom en clair profil: auto-description Amis(idu1, idu2, daterel): relations d'amitié entre les membres idu1, idu2: identifiants des utilisateurs qui sont des amis daterel: date à laquelle ils sont devenus amis Communauté(idg, idu, dateg): informations sur l'appartenance des utilsateurs aux groupes idg, idu: identifiants de l'utilisateur et du groupe auquel il appartient dateg: date à laquelle l'utilisateur a adhéré au groupe
Les requêtes sur la base de données sont exécutées en utilisant la fonction DB_execSQL($req, $serv) étudiée en TD, ou $req est la requête à exécuter, $serv est l'identifiant de la connexion. On suppose que l'exécution des requêtes se fait sans erreur. Question 1(1pt). Chaque groupe contient au moins un utilisateur. Donnez la fonction listemembres($id, $serv) qui retourne, sous forme de tableau, la liste des identifiants des utilisateurs du groupe identifié par $id. Si le groupe n'existe pas la fonction retourne NULL. Solution: function listemembre($id, $serv) { $req = ''select idu from Communauté where idg= ''.$id; $resultat = DB_exec_SQL($req, $serv); while($ligne = mysql_fetch_object($resultat)){ $liste[]=$ligne->idu; if(isset($liste)) return $liste; return NULL; Question 2(1pt). Un utilisateur peut appartenir à plusieurs groupes. Écrivez la fonction listegroupes($id, $serv) qui fait appel à la fonction listemembre et qui retourne un tableau associatif, où à chaque identifiant d'un groupe auquel appartient l'utilisateur identifié par $id, on associe le tableau de la liste des identifiants de tous les utilisateurs de ce groupe. Si l'utilisateur $id n'existe pas, la fonction retourne NULL. examli345mai2010.doc
Nom: Prenom : n :... page 13 Solution: function listegroupe($id, $serv) { $req = ''select idg from Communauté where idu= ''.$id.; $resultat = DB_exec_SQL($req, $serv); while($ligne = mysql_fetch_object($resultat)){ $liste[$ligne->idg]=listemembre($ligne->idg, $serv); if(isset($liste)) return $liste; return NULL; Question 3(1pt). Écrivez la fonction testappartenance($id, $listegroupes) qui retourne true si l'utilisateur $id appartient à au moins un des groupes dans le tableau associatif $listegroupes semblable au tableau retourné à la question 2. Dans le cas contraire la fonction retourne false. Solution: function testappartenance($id, $listegroupes) { foreach($listegroupes as $groupe->$listemembres){ foreach($listemembres as $membre){ if($membre == $id){ $trouve=true; break; if(isset($trouve)) return true; return false; Question 4(2pts). Écrivez une fonction rechercheamis($id, $serv) qui affiche sous forme de tableau HTML (avec une seule colonne), la liste des profils de tous les utilisateurs s'appelant 'Toto' (et différents de $id), qui ne sont pas déjà des amis de $id et qui appartiennent à un groupe auquel appartient $id. examli345mai2010.doc
Nom: Prenom : n :... page 14 Indication: vous pouvez utiliser la fonction sql_num_rows($resultat), qui retourne le nombre de lignes contenues dans $resultat ($resultat est retourné par DB_exec_SQL). Solution: function rechercheamis($id, $serv) { echo ''<TABLE border=1>''; echo ''<TR><TH> Utilisateurs</TH> </TR>''; $req=''select idu, profil from Utilisateurs where nom='toto' and idu!= $id'' ; $resultat = DB_exec_SQL($req, $serv); $listegroupe = listegroupe($id, $serv); while($ligne = mysql_fetch_object($resultat)){ if(!testappartenance($ligne->idu, $listegroupe)) continue; $req = '' select * from Amis where id1=''.$resultat->idu.'' and id2=$id''; $res = DB_exec_SQL($req, $serv); if(mysql_num_rows($res)!= 0) continue; echo echo''<tr><td>''.$ligne->profil.''</td></tr>''; echo ''</TABLE>''; Question 5(0,5pt). Comment doit-on modifier le code précédent pour ajouter une nouvelle colonne au tableau dans laquelle on affiche sur chaque ligne une case à cocher nommmée id_util_x et ayant comme valeur x, où x est l'identifiant de l'utilisateur appelé 'Toto' affiché sur la même ligne. Les cases sont déjà cochées. On ajoute également un bouton appelé «valider». Lorsque ce bouton de soumission est appuyé on fait appel à un script TraiterDemandes.php qu on suppose déjà existant.. examli345mai2010.doc
Nom: Prenom : n :... page 15 Solution: function ajoutamis($id, $serv) { echo ''<form action='traiterdemandes.php' method='post'>'' echo ''<TABLE border=1>''; echo ''<TR><TH> Utilisateurs</TH> <TH> Confirmer </TH> </TR>''; $req=''select idu, profil from Utilisateurs where nom='toto' and idu!= $id'' ; $resultat = DB_exec_SQL($req, $serv); $listegroupe = listegroupe($id, $serv); while($ligne = mysql_fetch_object($resultat)){ if(!testappartenance($ligne->idu, $listegroupe)) continue; $req = '' select * from Amis where id1=''.$ligne->idu.'' and id2=$id''; $res = DB_exec_SQL($req, $serv); if(mysql_num_rows($res)!= 0) continue; echo echo''<tr><td>''.$ligne->profil.''</td>''; echo ''<TD> <input type='checkbox' name=' ''. ''id_util_.$ligne->idu. '' ' value=' ''.$ligne->idu.'' ' CHECKED> </TD>''; echo ''</TR>''; echo ''</TABLE>''; echo ''<input type='submit' value='ok'>'' echo ''</form>''; examli345mai2010.doc