Bonnes Pratiques : PL/SQL, SOA et transactions

Vous devez intégrer des procédures PL/SQL, les encapsuler de manière unitaire, les faire intervenir dans un processus plus important ? A un moment risque de se poser la question de la gestion transactionnelle. Voici quelques bonnes pratiques et idées qui se sont un jour posées à nous.

Le problème rencontré

Pour situer un peu la problématique, des procédures PL/SQL étaient utilisées comme fournisseurs de service. Ces services pouvaient être complexes, provoquer des insertions dans plusieurs tables. Il y avait donc nécessité de mettre en place une gestion transactionnelle pour s’assurer que toutes les insertions soient cohérentes.
D’un point de vue des bonnes pratiques PL/SQL, il n’est pas bon de gérer dans les procédures la gestion de transactions (gestion de commit et rollback).
D’un point de vue SOA, la procédure PL/SQL en question est considérée, d’un point de vue conceptuel, comme étant un service métier responsable de l’intégrité de ses données (offre un service métier complet).

La recherche de la meilleure solution

A ce stade, chaque partie considère à la vue de ces informations que l’autre doit être le responsable de la transaction. Voici de manière simplifiée l’avancement pas à pas qui a permis de déterminer la bonne pratique à mettre en place.
Le principe utilisé est le suivant :

  • Mise en place de 2 tables, avec chacune un champ string de 10 caractères
  • Mise en place d’une procédure PL / SQL effectuant 2 inserts, un dans chaque table.
  • Mise en place d’un DBAdapter branché sur la procédure PL / SQL et fournissant les 2 valeurs à insérer.

Et la manière de réaliser les différents cas :

  • Cas valide : fourni 2 valeurs de moins de 10 caractères
  • Cas exception : fourni la 1ère valeur avec moins de 10 caractères, et la 2nde de plus de 10 caractères pour provoquer une exception à l’insertion
  • Cas erreur propre : modification de la procédure pour catcher l’exception et renvoyer un message normal.

Cas simple Mediator :

    santony_bp_plsql-soa-transac-01

  • La procédure PL/SQL est exposé simplement par un Mediator. L’exception est déclenchée, et remontée. La datasource a bien rollbacké la transaction.
  • La procédure PL/SQL est exposé simplement par un Mediator. L’exception est déclenchée, mais catché en interne. Un message « normal » est renvoyé (masquant l’exception), permettant de signifier que le traitement a échoué. La datasource a commité la transaction.

Ce 1er test a permis de mettre en évidence, que le comportement normal gère bien l’aspect transactionnel. Cependant, rien d’automatique ne peut être déclenché si l’exception n’est pas remontée.
Dans notre problème, le service métier PL/SQL masque en effet les exceptions, pour fournir à l’appelant un message propre. Dans le cadre d’une simple exposition par un Mediator, aucun moyen d’interpréter un retour en « erreur » n’existe, il est donc impossible de provoquer un rollback.

Cas simple BPEL :

santony_bp_plsql-soa-transac-02

Les mêmes tests ont été réalisés avec un appel au travers d’un BPEL. Bien entendu une datasource XA a été mise en place pour permettre d’étendre la transaction à davantage que le simple appel. Grace au BPEL, on peut interpréter le retour, et provoquer un rollback de la transaction.
Ce 2ème test nous a permis de voir que via un processus BPEL, on pouvait gérer l’appel de transaction. Maintenant on sait que l’on a un moyen de gérer dans la SOA-Suite l’aspect transactionnel. Cependant, est-ce acceptable de mettre en place un processus BPEL pour rendre une procédure PL/SQL unitaire transactionnellement correcte ?

L’appelant de plus haut niveau

Les précédents tests nous ont permis de voir que techniquement, notre problème pouvait avoir une solution. Cependant elle ne paraissait pas acceptable : ce n’est pas parce que l’on pouvait le faire que c’était la meilleure solution.
On dit souvent que l’appelant de plus haut niveau est celui qui a la connaissance de la nécessité de committer ou de rollbacker une transaction.
Dans notre cas, finalement, nous avons modélisé un exemple d’échange avec les procédures, tout en tenant compte que si un processus d’orchestration était nécessaire, c’était car il orchestrait plusieurs procédures :

santony_bp_plsql-soa-transac-03

A la vue de ce diagramme,  on s’est aperçu d’une forte ressemblance dans notre représentation, symbolisée par les parties en rouge.
En fin de compte le médiator est un composant technique, un « cablage ». Il n’a aucune réelle intelligence. Contrairement à un BPEL, ou une procédure PL/SQL… finalement, dans l’exposition via un Mediator d’une fonction métier, c’est cette fonction qui est l’appelant de plus haut niveau ! Dans ce cas précis, la règle serait donc que ce soit la procédure qui gère le commit/rollback. Mais dans ce cas, on viole les bonnes pratiques PL/SQL.
Voici un tableau qui présente suivant les langages une vision schématique des différentes couches, qui nous a permis de déterminer la meilleure solution à nos yeux :

santony_bp_plsql-soa-transac-04

Pour tous les autres services que nous exposions (Java, .NET), il s’agissait de web-services, non transactionnels. Les services exposés par ceux-ci étaient responsable de leur traitement, de l’intégrité de leurs données.
Finalement côté PL/SQL cette couche d’exposition n’existait pas… mais elle pouvait être mise en place facilement.

Conclusion

L’une des causes ayant amené à cette réflexion était les habitudes en place : le PL/SQL ne fournissait jamais de service métier en lui-même, mais était toujours un fournisseur de briques fonctionnelles élémentaires pour d’autres langages (Java, .NET). Aujourd’hui avec les outils SOA, il est possible de mettre en place un tel service sans enrobage externe (hors SOA).
Après toutes ces observations, il a été simple de définir la bonne pratique à respecter concernant l’aspect transactionnel associé à des procédures PL/SQL :

  • Si le PL/SQL expose un service métier complexe appelable unitairement, l’appelant s’attend à ce qu’il gère l’intégrité des données lors de son traitement.
    Une couche d’exposition sera à mettre en place pour que le service assure son aspect transactionnel.
  • Si le PL/SQL est utilisé comme une brique permettant  la construction d’un service métier de plus haut niveau, il n’a pas à gérer l’aspect transactionnel. Il pourra être réutilisé par des services métiers de plus haut niveau tout en leur déléguant l’aspect transactionnel.

Ainsi avec les même briques métier, et l’ajout d’une couche d’exposition, il a été possible de concilier les bonnes pratiques habituelles (pas de transactionnel) tout en ajoutant la notion de service métier indépendant à partir d’une procédure PL/SQL.

santony_bp_plsql-soa-transac-05

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *