• Aucun résultat trouvé

9.2 Algorithmes de g´ en´ eration des transactions

9.2.3 Initialisation

CREATE TABLE member (

memberKey int PRIMARY KEY, nbLoans int NOT NULL,

loanDuration int NOT NULL ) ;

9.2.3 Initialisation

L’initialisation de la BD est d´etermin´ee lors de l’analyse des clauses d’entr´ee ; il s’agit en effet d’un cas particulier de clause d’entr´ee dans les d´efinitions d’attri-buts. Pour chaque d´efinition d’attribut, il existe une clause de la forme “⊥ : u”. Cette derni`ere correspond au cas initial, puisque la trace t du syst`eme est vide. La valeur la plus courante pour l’expression u est “∅” pour une d´efinition de cl´e et “⊥” pour une d´efinition d’attribut non cl´e. Dans ce cas, la table corres-pondante ne contient aucun tuple `a l’initialisation.

9.2.4 Analyse des clauses d’entr´ee

Les r´esultats de l’analyse des clauses d’entr´ee (ligne (4) de l’algorithme g´en´eral) sont les suivants :

1. les attributs affect´es par l’action a, d´enot´es par Att (a), 2. les tables affect´ees par a, not´ees par T(a),

3. pour chaque table T de T(a),

– les valeurs de cl´e des tuples `a supprimer de la table T , not´ees par KDelete(T , a),

– les valeurs de cl´e des tuples `a ins´erer ou `a mettre `a jour dans T , not´ees par KChange(T , a).

Dans la suite de cette th`ese, les expressions de la forme eKey(front (s)) et b(front (s), k1, ..., km) sont simplifi´ees respectivement par eKey() et b(k1, ..., km), car les appels de d´efinitions d’attributs dans les clauses d’entr´ee portent toujours sur front (s).

9.2.4.1 Algorithme

Pour calculer T(a), il faut d´eterminer, pour chaque attribut b de Att(a), la table de b, not´ee par table(b), grˆace aux d´efinitions de tables g´en´er´ees dans la

9.2. ALGORITHMES DE G ´EN ´ERATION DES TRANSACTIONS 155 section9.2.2. Alors, l’ensemble T(a) est d´efini par :

T(a) = {table(b) | b ∈ Att (a)}

Soit T une table de T(a). Afin de calculer KDelete(T , a) et KChange(T , a), on consid`ere, pour chaque attribut b de Att (a) tel que la table de b soit T , l’ensemble (qu’on appelle KD(b) dans la suite) des valeurs de cl´e des tuples `a supprimer d’apr`es la d´efinition de b, et l’ensemble (not´e KIU(b)) des valeurs de cl´e des tuples `a ins´erer ou `a mettre `a jour d’apr`es la d´efinition de b. Formelle-ment, il faut d´eterminer, pour chaque attribut b de Att (a), les ensembles KD(b) et KIU(b) tels que :

KDelete(T , a) = ∪{b∈Att(a)∧table(b)=T }KD(b) KChange(T , a) = ∪{b∈Att(a)∧table(b)=T }KIU(b)

Les ensembles KD(b) et KIU(b) sont d´etermin´es par analyse des clauses d’entr´ee. L’algorithme est le suivant :

d´eterminer Att (a)

pour chaque attribut b de Att (a)

si b est d´efini par un terme conditionnel g´en´erer un arbre de d´ecision pour b

d´eterminer les requˆetes SQL d’interrogation d´efinir les variables et les tables temporaires d´eterminer table(b), KIU(b), KD(b)

calculer T(a)

pour chaque T dans T(a)

calculer KDelete(T , a),KChange(T , a)

Pour retrouver dans la BD les tuples caract´eris´es en eb3 par les pr´edicats des termes conditionnels, des requˆetes SQL d’interrogation sont g´en´er´ees. Ces requˆetes sont d´efinies par nos algorithmes sous la forme d’´enonc´es SELECT. La g´en´eration des ´enonc´es SQL est d´etaill´ee dans le chapitre10. Les autres ´etapes de l’algorithme sont pr´esent´ees dans les sections suivantes.

9.2.4.2 Calcul de Att (a)

L’ensemble Att (a) est d´efini comme B (a) dans le cas de la traduction vers B (voir section6.3.2). Un attribut b est affect´e par l’action a s’il existe au moins une clause d’entr´ee de la forme “a(−→p ) : u” dans la d´efinition de b. Par exemple, l’action Transfer apparaˆıt dans les d´efinitions d’attributs de nbLoans, dueDate et borrower ; par cons´equent, nous avons :

Att (Transfer) = {nbLoans, dueDate, borrower } 9.2.4.3 Calcul de KD(b) et KIU(b)

Les ensembles KD(b) et KIU(b) sont tout d’abord initialis´es `a “∅”. Nous rappelons que, pour chaque attribut b de Att (a), plusieurs clauses d’entr´ee de la forme “a(−→p

j) : uj” peuvent ˆetre d´efinies pour la mˆeme action a. Ces clauses sont alors analys´ees dans l’ordre de leur d´eclaration dans la d´efinition d’attribut correspondante. Comme dans la section6.3.2.2, une substitution θuj est d´efinie

pour chaque clause d’entr´ee ; elle permet de relier les param`etres actuels de la clause aux param`etres formels de l’action.

Les ensembles KD(b) sont calcul´es uniquement pour les d´efinitions de cl´e. Si b est une d´efinition de cl´e, alors l’expression uj est un terme fonctionnel et une valeur v a ´et´e d´etermin´ee par analyse du filtrage. Si le terme uj contient le symbole “−”, alors la valeur v est ajout´ee `a l’ensemble KD(b) ; sinon, elle est ajout´ee `a l’ensemble KIU(b). Par exemple, la clause d’entr´ee de Discard dans la fonction bookKey est associ´ee `a l’expression suivante : bookKey() − {bId }. Par cons´equent, on a : KD(bookKey) = {bId }.

Pour calculer les ensembles KIU(b), nous consid´erons `a la fois les d´efinitions de cl´e et les d´efinitions d’attributs non cl´e. Si l’expression uj de la clause d’entr´ee est un terme fonctionnel, alors une valeur de cl´e v a ´et´e enti`erement d´etermin´ee. D’un autre cˆot´e, si uj est un terme conditionnel, alors il faut analyser les diff´erentes conditions des pr´edicats dans les parties if. Les va-riables dans −→

k ∩ var (−→p

j) sont d´etermin´ees par le filtrage θuj, alors que les variables dans−→

k − var (−→p

j) sont d´etermin´ees par les conditions du terme condi-tionnel uj. Comme pour la traduction vers B, nous utilisons des arbres de d´ecision afin d’identifier et d’analyser les valeurs de cl´e caract´eris´ees par les pr´edicats des parties if des termes conditionnels. Ces arbres ont ´et´e d´efinis dans la section 6.3.2.2. Les feuilles de l’arbre de d´ecision sont des termes fonc-tionnels d´efinis dans les clauses then de l’expression uj et ses branches sont ´

etiquet´ees par les pr´edicats d´ecrits dans les clauses if. En analysant l’arbre de d´ecision, il est possible de d´eterminer un ensemble de tuples KVj ,i pour chaque feuille f tj ,i de l’arbre. Chaque ´el´ement de KVj ,i est ajout´e `a KIU(b). Par exemple, dans le cas de l’action Transfer pour la fonction nbLoans, on ob-tient : KIU(nbLoans) = {mId0, borrower (bId )}.

9.2.4.4 D´efinition de variables et de tables temporaires

Les valeurs de cl´e `a ins´erer, `a mettre `a jour ou `a supprimer sont caract´eris´ees en eb3 par des pr´edicats du premier ordre dans les termes conditionnels. Pour retrouver les tuples correspondants dans les tables de la BD, des ´enonc´es de type SELECT sont d´efinis dans les transactions Java/SQL qui sont g´en´er´ees par nos algorithmes. Une variable temporaire est d´efinie au niveau du langage hˆote (en l’occurrence Java) lorsqu’un seul enregistrement de la table est concern´e, tandis qu’une table temporaire est cr´e´ee quand plusieurs enregistrements sont en jeu. Ces d´efinitions permettent de manipuler les donn´ees en question dans la transaction `a g´en´erer. La d´efinition des variables et des tables temporaires est coupl´ee avec l’analyse des arbres de d´ecision, d´ecrite dans les paragraphes pr´ec´edents. La g´en´eration des ´enonc´es SELECT qui correspondent aux valeurs caract´eris´ees par les pr´edicats des termes conditionnels est pr´esent´ee dans le chapitre10.

Pour les besoins de cette th`ese, un pseudo-code de haut niveau est utilis´e pour d´ecrire les transactions g´en´er´ees par nos algorithmes. Dans la pratique, ce pseudo-code est traduit en Java. Par exemple, pour caract´eriser l’ensemble des livres emprunt´es par le membre identifi´e par mId , la table suivante est g´en´er´ee :

CREATE TEMPORARY TABLE TAB (bookKey int PRIMARY KEY) ; INSERT INTO TAB

9.2. ALGORITHMES DE G ´EN ´ERATION DES TRANSACTIONS 157 SELECT loan.bookKey

FROM loan

WHERE loan.borrower = #mId ;

Par convention, une variable utilis´ee dans un ´enonc´e SQL est pr´efix´ee par le symbole “#”, afin de la distinguer des noms d’attributs.

Les variables et les tables temporaires sont d´efinies au d´ebut de chaque transaction, parce que les pr´edicats des termes conditionnels impliquent toujours les valeurs d’attributs qui sont valables avant l’ex´ecution de la transaction. Par cons´equent, nous avons d´efini les variables et les tables de telle sorte qu’elles soient ind´ependantes de l’ordonnancement des ´enonc´es DUI. D’autre part, nous utilisons des tables temporaires, plutˆot que des vues, afin d’´eviter qu’un ´enonc´e DUI ult´erieur de la transaction ne modifie la valeur des ensembles de tuples `a traiter.

9.2.5 D´efinition des transactions

Pour d´efinir les transactions Java/SQL, tous les ´enonc´es DUI sont group´es par table. Grˆace `a l’analyse des clauses d’entr´ee, les ´enonc´es de type DELETE ont ´et´e distingu´es des autres ´enonc´es SQL. Les enregistrements `a supprimer de la table T sont indiqu´es dans l’ensemble KDelete(T , a). Ces ´enonc´es sont group´es au d´ebut de la liste d’instructions de chaque table. En effet, la syntaxe des d´efinitions d’attributs eb3 n’autorise pas, dans les d´efinitions de cl´e, des expressions de la forme eKey()∪{...}−{...}, qui pourraient impliquer un ordre entre les ´enonc´es de type DELETE et les autres. En fait, le probl`eme ne se pose pas, car de telles expressions peuvent toujours ˆetre r´e´ecrites en des expressions ´equivalentes de la forme eKey()−{...}∪{...}.

L’analyse des clauses d’entr´ee ne permet pas de distinguer les tuples `a ins´erer de ceux `a mettre `a jour. En effet, une expression de la forme “eKey()∪{k }” correspond soit `a une insertion, soit `a une mise `a jour, suivant que les deux ensembles sont disjoints ou pas. La mod´elisation en eb3 ne permet donc pas de faire cette distinction, `a cause du niveau d’abstraction et de l’utilisation de la th´eorie des ensembles. Ces types d’´enonc´es DUI impliquent tous les deux l’utilisation de l’op´erateur “∪” dans les d´efinitions d’attributs, car les effets sur la BD sont les mˆemes : un tuple identifi´e par la cl´e k doit appartenir `a la BD apr`es l’ex´ecution de la transaction. Dans la traduction vers B, nous n’avions pas ce probl`eme, car l’op´erateur de surcharge ( “<+” ) correspond exactement `a ce comportement. Dans le cadre de la synth`ese de transactions, nous avons choisi de coder les deux interpr´etations possibles de l’expression avec un ´enonc´e SQL complexe. Ainsi, les expressions avec le symbole “∪” sont impl´ement´ees par une mise `a jour, suivie d’une insertion.

Soit T une table de T(a). Pour chaque k dans KChange(T , a), un ensemble L = {UPD1, ..., UPDp} d’´enonc´es de type UPDATE est g´en´er´e pour chaque attribut b de T , affect´e par l’action a et tel que k ∈ KIU(b). D’autre part, un ´enonc´e de type INSERT est ´egalement g´en´er´e pour k et le mˆeme ensemble d’attributs. Ensuite, on consid`ere le premier ´enonc´e de type UPDATE (notons-le UPD1, mais l’ordre n’a pas d’importance ici) et une conditionnelle est d´efinie de mani`ere `a d´eterminer si UPD1 a effectivement mis `a jour la BD. Si c’est le cas, alors les autres ´enonc´es de L sont aussi ex´ecut´es. Sinon, l’´enonc´e de type INSERT est ex´ecut´e. Le sous-algorithme pour la ligne (9) de l’algorithme

g´en´eral pr´esent´e dans la section9.2.1est le suivant : pour chaque k dans KDelete(T , a)

d´eterminer and g´en´erer les ´enonc´es de type DELETE avec k pour chaque k dans KChange(T , a)

pour chaque attribut b de T dans Att (a) si k est dans KIU(b)

calculer la valeur b(k )

d´eterminer l’ensemble L des ´enonc´es de type UPDATE not´es UPDl, 1 ≤ l ≤ p, pour k et les b(k )

d´eterminer l’´enonc´e de type INSERT, not´e INS , pour k et les b(k ) g´en´erer UPD1

g´en´erer l’instruction suivante : IF SQL%NotFound THEN INS

ELSE UPD2; ... UPDp; END ;

o`u la variable “SQL%NotFound” contient une valeur retourn´ee par le SGBD qui indique si la mise `a jour a effectivement modifi´e le tuple dans la table.

Par exemple, la transaction g´en´er´ee pour Discard est : TRANSACTION Discard(bId : int)

DELETE FROM book WHERE bookKey = #bId ; COMMIT ;

Cette d´efinition est simple, car l’action Discard ne fait que supprimer le tuple identifi´e par la cl´e bId . En revanche, lorsque l’action implique des insertions ou des mises `a jour, alors la transaction g´en´er´ee est plus complexe. Par exemple, on obtient pour Acquire :

TRANSACTION

Acquire(bId :int,bTitle :varchar(20)) /* mise `a jour */

UPDATE book SET title = #bTitle WHERE bookKey = #bId ;

/* conditionnelle */ IF SQL%NotFound THEN

/* insertion */

INSERT INTO book(bookKey,title) VALUES (#bId,#bTitle) ;

END ; COMMIT ;

La partie ELSE de la conditionnelle n’est pas indiqu´ee ici, car une seule mise `

a jour a ´et´e g´en´er´ee pour Acquire. Cet exemple d´emontre que la transaction g´en´er´ee a effectivement le comportement attendu, mˆeme si sa d´efinition com-porte des instructions inutiles. En r´ealit´e, nous savons par notre compr´ehension de la sp´ecification compl`ete de la biblioth`eque (notamment, en analysant les expressions de processus eb3) que l’action Acquire est un producteur de livre. Par cons´equent, l’´enonc´e de type UPDATE ne sera jamais ex´ecut´ee parce que l’entit´e mId ne peut pas exister dans la BD avant l’ex´ecution de son producteur.