Master 1 d'Informatique - Option MAD (Middleware et Applications aDaptables) - Université
Grenoble I - UFR IMA
Aspect-Oriented Programming / AspectJ
Enseignant : Sara Bouchenak, Sara.Bouchenak@imag.fr
Page de l'option MAD :
http://sardes.inrialpes.fr/~bouchena/teaching/MAD/
TP 3 : Transactions
- Objectif
- Environnement logiciel
- Application bancaire
persistante
- Système transactionnel
- Ajout des
transactions à l'application bancaire
- Mise en oeuvre
des transactions avec AspectJ
- Combinaison des
transactions et du traçage
- Compte-rendu global
Conception et mise en oeuvre d'un système transactionnel avec AOP/AspectJ.
Les logiciels suivants sont nécessaires au TP ; les installer s'ils ne sont
pas disponibles dans votre environnement.
Logiciels
En plus des logiciels utilisés dans les TP précédents :
Les logiciels nécessaires au TP sont également disponibles dans ~sbouchen/ENS/MAD/AOP/Soft/
Variables d'environnement
Définir la variable d'environnement suivante :
En plus des variables utilisées dans les TP précédents :
- JAVA_HOME
- ASPECTJ_HOME
- ANT_HOME
- PATH (inclut JAVA_HOME/bin, ASPECTJ_HOME/bin, ANT_HOME/bin)
Exemple de fichier de commandes pour Unix/tcsh env-tcsh (soit ajouter ces commandes à votre fichier
~/.cshrc, soit exécuter la commande source env-tcsh).
Exemple de fichier de commandes pour Windows env-win.bat (exécuter la commande env-win.bat).
Ces fichiers sont disponibles dans ~sbouchen/ENS/MAD/AOP/Soft/
Récupérer le TP3 qui se trouve dans ~sbouchen/ENS/MAD/AOP/Project/TP3.tgz
Une application bancaire persistante est donnée dans Project/TP3/Basic :
- Dans Project/TP3/Basic/docs/api/index.html,
l'interface de programmation de l'application est fournie. Cette interface est
similaire à celle utilisée dans le TP2.
- Project/TP3/Basic/src/ contient le
code source de l'application. Cette application est persistante ; elle utilise
une base de données pour stocker, de manière persistante, les informations
relatives aux comptes bancaires.
Configurer la base de données McKoi :
- Choisir un numéro de port sur lequel votre serveur de BD McKoi sera lancé.
Si lors du lancement de votre serveur McKoi (avec la commande ant create_db),
vous avez une exception avec le message "Address already in use" ou "Journal
file already exists", c'est que le numéro de port que vous avez choisi est
déjà utilisé par quelqu'un d'autre.
Choisir alors un autre numéro.
- Dans le fichier db.conf, mettre mettre à jour la valeur de
jdbc_server_port ave le numéro de port choisi.
- Dans le fichier build.xml, mettre à jour la valeur de la propriété
mckoi.port avec le même numéro de port.
Compiler et exécuter l'application puis naviguer dans son API et son code
pour comprendre son fonctionnement :
- Commande de compilation : ant compile
- Lancement du serveur de base de données : ant create_db
- Sur une autre console, initialisation de la base de données : ant
pop_db
Ceci créera une base de données avec une table accounts qui contient
trois colonnes : id (le numéro de compte), customer (le nom du
propriétaire du compte) et balance (la balance du compte).
La commande d'initialisation crée sept entrées dans cette table.
- Lancement d'un client graphique de la base de données : ant client_db
Ce client graphique permet d'exécuter des requêtes SQL sur la base de données.
Tester par exemple la requête SHOW TABLES qui affiche les tables de la
base de données et la requête SELECT * FROM accounts qui affiche toutes
les informations concernant toutes entrées de la table accounts.
N.B. Vérifier que vous avez un serveur X lancé, tel que X-Win32 pour Windows.
- Sur une autre console, lancer le programme de test : ant run
Ce programme ajoute deux nouvelles entrées à la table accounts et
effectue des transferts entres ces comptes.
- Utiliser le client graphique précédemment lancé pour faire afficher le
nouveau contenu de la table accounts (requête SQL SELECT * FROM
accounts )
Problématique : Incohérence
L'application bancaire propose, entre autres, d'effectuer des transferts
d'une certaine somme d'argent entre deux comptes bancaires (voir la méthode
banking.InterAccountOperations.transfer). Un transfert est ainsi constitué
de deux opérations : une opération de débit sur un compte et une opération de
crédit sur un autre compte.
Que se passe-t-il si la première opération s'effectue avec succès et qu'un
problème intervient lors de la seconde opération ?
La base de données de l'application bancaire serait dans un état incohérent (une
somme d'argent a disparu).
Transactions : Garantie de la cohérence
Pour éviter cette incohérence, les deux opérations constituant un transfert
doivent s'effectuer dans une transaction. Une transaction définit une
unité atomique qui garantit que le système reste cohérent avant et après
l'exécution de la transaction.
De façon générale, une transaction est caractérisée par quatre propriétés
ACID : Atomicité, Cohérence, Isolation et Durabilité. L'atomicité garantit que
soit toutes les opérations d'une transaction sont effectuées avec succès
(transaction validée), soit aucune d'elles n'est effectuée (transaction annulée).
Dans ce TP, nous nous intéresserons plus particulièrement à la propriété
d'atomicité.
Le répertoire Project/TP3/Transactions_HandCoded/ contient une extension "programmée
à la main" de l'application bancaire pour la prise en compte des
transactions.
Les principales modifications apportées à l'application sont les suivantes :
- Désactiver le mode auto-commit afin d'éviter que les opérations ne soient
validées individuellement et qu'elles soient plutôt validées à la fin d'une
transaction.
Pour cela, un appel à setAutoCommit(false) a été ajoutée à la fin de la
méthode banking.DatabaseImpl.getConnection.
- Utiliser la même connexion à la base de données pour effectuer les
opérations de mise à jour constituant une transaction.
Pour cela, la connexion utilisée par chaque opération (méthode) d'une
transaction est passée comme paramètre supplémentaire à l'opération. Voir les
nouvelles versions des méthodes debit, credit, getBalance
et setBalance de la classe banking.DatabaseAccountImpl et les
nouvelles versions des
méthodes query et update de la classe banking.DatabaseImpl.
- Valider les opérations d'une transaction à la fin de cette transaction si
toutes les opérations imbriquées se sont terminées avec succès, sinon annuler
la transaction.
Pour cela, des appels aux méthodes commit et rollback n'ont été
ajoutés qu'à la méthode de plus haut niveau dans la transaction et pas aux
méthodes imbriquées (méthode banking.InterAccountOperations.transfer et
pas les méthodes banking.DatabaseAccountImpl.debit,
banking.DatabaseAccountImpl.credit,
banking.DatabaseAccountImpl.getBalance,
banking.DatabaseAccountImpl.setBalance, banking.DatabaseImpl.query,
banking.DatabaseImpl.update).
Proposer une mise en oeuvre de l'aspect de transactions en utilisant AspectJ.
Pour ce faire, copier le répertoire Project/TP3/Transactions_Aspects/ et écrire l'aspect demandé dans
Project/TP3/Transactions_Aspects/aspects/transaction/TransAspect.java.
Pour la compilation et les tests, penser à utiliser ant compile_aj et ant run_aj.
Quelques directions
- Utiliser la même connexion à la base de données (même objet
java.sql.Connection) pour effectuer les mises à jour d'une transaction
dans la base de données.
Penser à l'utilisation de percflow qui crée une instance d'aspect par
flot de contrôle (thread Java). Ainsi, à chaque flot de contrôle exécutant une
transaction, il est possible d'associer une instance d'aspect distincte et
donc, un objet java.sql.Connection distinct de ceux utilisés par les
flots exécutant les autres transactions.
La solution préconisée ici est différente de celle proposée dans la version Project/TP3/Transactions_HandCoded/
puisqu'ici, la connexion utilisée par une transaction est celle associée au
flot de contrôle sous-jacent alors que dans Project/TP3/Transactions_HandCoded/,
la connexion utilisée par une transaction est passée en paramètre des
opérations constituant cette transaction.
- Désactiver le mode auto-commit afin d'éviter que les opérations ne soient validées
que lors du succès d'une
transaction.
Pour cela, faire appel à setAutoCommit(false) lors de la création d'une
nouvelle connexion.
- Valider les opérations d'une transaction à la fin de cette transaction si
toutes les opérations imbriquées se sont terminées avec succès, sinon annuler
la transaction.
Pour cela, faire appel aux méthodes commit et rollback dans la
méthode de plus haut niveau dans une transaction.
Pour savoir si une méthode imbriquée dans une transaction est de plus haut
niveau, penser à l'utilisation de cflowbelow.
Pour l'appel aux méthodes commit et rollback, voir l'exemple
donné dans Project/TP3/Transactions_HandCoded/src/banking/InterAccountOperations.java
Combiner l'utilisation de l'aspect de traçage proposé dans le TP2 et de
l'aspect de transactions proposé dans ce TP à votre application bancaire.
Pour cela, vous ne devez pas modifier le code de vos aspects ni le code de
l'application mais utiliser le compilateur AspectJ avec ces deux aspects et
l'application bancaire.
Un compte-rendu global sur les TP 2, 3 et 4 est à rendre lors de la séance de
démonstration.
Voir ici pour plus d'informations.