Application de commerce électronique

Etape 4 - Gestion transactionnelle d'ordres d'achats

                                              F. Boyer, S. Chassande, D. Feliot, S. Krakowiak, D. Donsez
Projet de DESS-GI option SRR  et RICM3 option SR
Année Universitaire 2001-2002
Université Joseph Fourier, Grenoble


PLAN

1. Objectifs
2. Principes d'implémentation
2.1 Hiérarchie transactionnelle
2.2 Contrôle de l'atomicité
3. Réalisation du protocole
Bibliographie

1. Objectifs

L'émission d'un ordre d'achat d'un client vers le serveur de commerce doit déclencher l'exécution des actions suivantes : Ces trois étapes forment une transaction car elles doivent respecter la cohérence de l'ensemble du système comprenant le serveur de commerce électronique, les banques, les fournisseurs et les clients. Les conditions nécessaires au respect de la cohérence du système sont l'atomicité et la permanence.

Au cours du déroulement d'une transaction, le système passe par des états transitoires durant lesquels certaines contraintes d'intégrités ne sont plus respectées. Il est donc impératif qu'une transaction s'exécute entièrement ou soit complètement annulée : la séquence d'actions constituant la transaction est indivisible, c'eat a dire atomique.
Une transaction doit en outre assurer la permanence des modifications des données qui ont été effectuées.

Le traitement d'un ordre d'achat fait donc passer le système d'un état cohérent initial à un état cohérent final. L'ensemble du système étant distribué sur plusieurs sites, la transaction est dite répartie.

2. Principes d'implémentation

2.1 Hiérarchie transactionnelle
Nous proposons de réaliser un serveur CORBA spécialisé dans la gestion des transactions bancaires, afin de conserver une certaine indépendance entre l'application bancaire et le serveur de commerce. Les sites participant à la transaction commerciales sont alors : Le serveur de commerce initie la transaction d'achat : c'est le coordinateur global. Le serveur de transactions bancaires agit comme un coordinateur local ; il gère la transaction qui débite un compte client et crédite l'ensemble des comptes des fournisseurs. Le schéma ci-dessous représente la hiérarchie des intervenants dans la transaction d'achat.
 







2.2 Contrôle de l'atomicité : protocole de validation à deux phases
La propriété d'atomicité doit être garantie dans le cadre d'un système réparti. Le mécanisme de validation doit assurer que toutes les mises à jour sont exécutées sur tous les sites ou qu'aucune ne le soit. Or chaque site est responsable de la validation des modifications locales effectuées par la transaction. En conséquence il est nécessaire de coordonner l'ensemble des validations afin d'empêcher la création d'incohérences.

Le protocole de validation à deux phases permet de coordonner les validations des actions effectuées par tous les sites participant à la transaction. Le principe consiste ici à diviser la transaction en deux phases. La phase 1 réalise la préparation des mises à jour des objets modifiés par la transaction. La phase 2, réalisée seulement en cas de succès de la phase 1, intègre effectivement les résultats des mises à jour.
Le contrôle du système réparti est centralisé sous la direction d'un site appelé coordinateur global, les autres étant des participants.

Lors de l'étape 1, le coordinateur global demande aux autres sites s'ils sont prêts à commettre leurs mises à jour par l'intermédiaire du message Prepare. Si tous les participants répondent positivement, le message Commit est diffusé : tous les participants effectuent leur validation. Si un participant n'est pas prêt et répond négativement, le coordinateur demande à tous les autres sites de défaire la transaction.

Chaque intervenant (coordinateur global, participant) suit un diagramme d'état donné. Dans notre cas, le serveur de transactions bancaires, qui joue le role de coordinateur local,  suit le diagramme d'état d'un participant.
 

2.2.1 Coordinateur :
INITIAL : la récéption de l'odre Begin  par le coordinateur fait passer celui-ci dans l'état INITIAL. Dans cet état, un identificateur de transaction est alloué, et diverses initialisations sont effectuées (journaux, etc).

PREPARE : la récéption de l'ordre Prepare par le coordinateur fait passer celui-ci dans l'état PREPARE. Dans cet état, il effectue la préparation de la transaction, qui consiste :

Dans tous les cas, on doit assurer que les actions effectuées pendant la phase de préparation sont par la suite :
COMMIT : le coordinateur passe de l'état PREPARE à l'état COMMIT lorsqu'il a recu le message VoteOK de la part de tous les participants à qui il avait envoyé une requête Prepare. Dans cet état, il effectue les actions suivantes :
Une panne du coordinateur durant l'état COMMIT engendre le "re-jeu" du COMMIT, jusqu'à ce que les deux étapes citées ci-dessus soient terminées.
 
 

ABORT : le coordinateur passe de l'état PREPARE à l'état ABORT lorsqu'il à recu le message VoteKO de la part de l'un des participants à qui il avait envoyé une requête Prepare. Il passe également dans cet état si une panne arrive durant l'état PREPARE. Dans cet état, il effectue les actions suivantes :

Une panne du coordinateur durant l'état ABORT engendre le "re-jeu" de l'ABORT, jusqu'à ce que les deux étapes citées ci-dessus soient terminées.
2.2.2 Participant :
PREPARE : la récéption de l'ordre Prepare par un participant fait passer celui-ci dans l'état PREPARE. Dans cet état, il effectue la préparation de la transaction, qui consiste :
Dans tous les cas, on doit assurer que les actions effectuées pendant la phase de préparation sont par la suite :
READY : READY est l'etat intermédiaire entre PREPARE et COMMIT/ABORT pour un participant. Le participant passe automatiquement de l'état PREPARE à l'état READY lorsqu'il a fini d'exécuter les deux étapes du PREPARE. Dans cet état, il n'effectue pas d'actions, mais garantit simplement qu'en cas de panne, il est capable de se retrouver dans le même état que celui précédent la panne (état a la sortie du PREPARE), afin d'enchainer sur un COMMIT ou sur un ABORT.

COMMIT : le participant passe de l'état READY à l'état COMMIT lorsqu'il recoit le message Commit de la part du coordinateur. Dans cet état, il effectue les actions suivantes :

Si une panne du participant arrive durant l'état COMMIT, alors le coordinateur ne recevant pas de réponse à sa requête Commit, demandera le rejeu du COMMIT au participant.
 
 

ABORT : le participant passe de l'état READY à l'état ABORT lorsqu'il recoit le message Abort de la part du coordinateur.  Dans cet état, il effectue les actions suivantes :

Si une panne du participant arrive durant l'état ABORT, alors le coordinateur ne recevant pas de réponse à sa requête Abort, demandera le rejeu du ABORT au participant.
2.2.3 Opérations idempotentes
On peut remarquer que les opérations de COMMIT ou d'ABORT peuvent être rejouées plusieurs fois par tout intervenant dans la transaction.  On devra s'assurer que cela ne pose pas de problèmes, en rendant ces opérations idempotentes si cela est nécessaire.
On pourra toutefois accepter que l'unicité des messages adressés aux clients et aux fournisseurs (envois des clés et des commandes) ne soit pas assurée. Un fournisseur peut donc recevoir plusieurs commandes ayant le même identificateur de transaction. La gestion des commandes doit ignorer les duplicatas.

2.2.4 Traitement des pannes
On a pu remarquer à la lecture de la section précédente que les actions qui sont à effectuer en cas de panne dépendent de l'état dans lequel se trouve l'intervenant au moment de la panne. Pour connaître cet état, ainsi que pour être capable de "défaire" certaines actions, on utilisera des journaux (logs) dans lequel on enregistrera de manière synchrone les informations pertinentes. Le schéma de base est le suivant :

En cas de panne ou d'impossibilité à poursuivre la transaction, un intervenant doit être capable de défaire les actions déjà exécutées. Dans le doute, il peut décider de défaire une action qu'il n'a pas effectuée.
 

Si le coordinateur tombe en panne après l'émission du message PREPARE, tout participant ayant voté prêt est alors bloqué en attente de recevoir le message COMMIT ou ABORT. Les participants attendent donc que le coordinateur redémarre. Une solution serait de forcer après un certain délai la transaction locale à passer dans l'état ABORT.  Le protocole de validation à trois phases permet de résoudre ce problème, mais pour des raisons de simplicité, il ne sera pas implémenté dans l'application demandée.

Les tableaux ci-dessous présentent les différentes pannes possibles et les reprises correspondantes.
 
Etat du coordinateur lors de la Panne Reprise après panne
INITIAL la transaction est oubliée
PREPARE annuler les actions effectuées (passer dans l'état ABORT)
COMMIT reprendre le COMMIT
ABORT reprendre l'ABORT

 
 
Etat du participant lors de la Panne Reprise après panne
INITIAL la transaction est oubliée
PREPARE annuler les actions effectuées (passer dans l'état ABORT)
READY remettre le participant dans l'état READY 
COMMIT remettre le participant dans l'état READY 
ABORT remettre le participant dans l'état READY
3. Réalisation du protocole
Le protocole de validation utilisera le support de communication CORBA. L'implémentation des participants à la transaction nécessite de poser certaines hypothèses sur le support de communication utilisé :

Le protocole IIOP utilise des connexions TCP. SMTP (Simple Mail Transfer Protocol) est également basé sur des connexions TCP. Or TCP répond aux hypothèses posées.

Les envois de messages PREPARE, COMMIT ou ABORT par le servlet de gestion des ordres d'achat, ainsi que par le serveur de transactions bancaires, seront réalisés par des simples appels de méthodes distribués (requêtes CORBA). Un retour normal de l'appel de méthode prepare signifiera que le participant a donné son accord pour la validation de la transaction. Un retour avec exception levée par CORBA ou par le participant signifiera que le participant est tombé en panne, ou bien a donné son désaccord pour valider la transaction.

Le schéma ci-dessous illustre le déroulement possible d'une transaction. L'opération d'enregistrement de l'ordre d'achat n'est pas représentée.
De même les envois de commandes et de la clé n'apparaissent pas. Ils sont effectués dans la phase de validation.

       
       
Serveur de commerce
L'ordre d'achat envoyé par le client est reçu par un servlet. La transaction d'achat qui débute alors sera modélisée par un objet Java de classe TransactionAchat, dont les principales méthodes sont les suivantes : L'enregistrement des ordres d'achat s'effectuent sur le site du serveur de commerce. L'atomicité est contrôlée par propagation en continu : les ordres d'achat sont directement écrits dans la base de données pendant la phase de préparation. En cas de retour-arrière (rollback), les enregistrements doivent être effacés.
Remarque : l'atomicité aurait pu être gérée directement par la base de données. Cependant la base choisie ne gère pas les transactions (elle fonctionne en mode auto-commit).

Lors du commit, le serveur de commerce valide la transaction bancaire, envoit l'identificateur de la transaction au client comme preuve de son achat (mailClient) et transmet les commandes de produits aux fournisseurs (mailFournisseur).

En cas de panne, la reprise sera gérée par un programme spécial (Recover), qui se charge d'effectuer le traitement adéquat en fonction de l'état dans lequel se trouvait le serveur au moment de la panne.

Serveur de transactions bancaires
Ce serveur de transactions bancaires est accessible au travers d'une interface IDL, dont les méthodes définies permettent :

Une transaction bancaire sera modélisée par un objet Java de classe TransactionBancaire, dont les principales méthodes sont les suivantes. Lorsque le serveur reçoit l'ordre de préparer le transfert bancaire, il crée un objet TransactionBancaire auquel il associe un identificateur.  L'appel de prepare sur cet objet engendre un contact auprès des banques puis des agences pour obtenir les comptes bancaires participant au transfert. Puis, une préparation est demandée auprès de chaque compte.

En cas de panne, le relancement du serveur de transactions bancaires procèdera automatiquement à la reprise de la panne si besoin est. Si la panne a eu lieu alors qu'une transaction était dans l'état READY, un nouvel objet TransactionBancaire sera créé pour représenter cette transaction, et reinitialisé convenablement pour que la transaction se retrouve à nouveau dans l'état READY.

Comptes
Un objet Compte est également un objet persistant. En conséquence, il hérite de la méthode save lui permettant de sauvegarder son état de façon atomique. Ceci permettra de gérer plus facilement la réalisation d'opérations atomiques sur ce type d'objets, en enregistrant les informations relatives aux transactions le concernant directement dans son état.
 

Bibliographie
Construction des systèmes d'exploitation répartis (R. Balter, J.-P. Banâtre, S. Krakowiak)