L'endroit où je travaille essaie d'établir des règles de base, et le débat que nous avons maintenant concerne les bibliothèques locales et les services Web pour la réutilisation du code. Les services Web semblent être le choix populaire dans la plupart des entreprises, et c'est vers cela que la plupart des développeurs se tournent.
Je ne vois tout simplement pas comment vous pouvez utiliser efficacement les services Web pour tout travail sérieux. Comment puis-je exécuter plusieurs appels de service en toute sécurité si je ne peux pas utiliser une transaction?
Disons que j'ai un travail cron qui saisit les clients de notre base de données qui remplissent une certaine condition dont ils doivent être informés. Ils reçoivent un fax, un e-mail et un ticket est créé pour suivre le problème en interne. C'est 3 appels de service différents qui se produiraient pour chaque client dans une boucle for.
Si une erreur se produit quelque part, il est possible, par exemple, qu'un fax et un e-mail soient envoyés au client, mais qu'un ticket ne soit pas créé. Ou pire, ce travail cron peut contenir un bogue qui provoque son échec au même point à chaque fois, et il envoie plusieurs fois un e-mail au même client. Si les bibliothèques étaient toutes locales, tout pourrait simplement être enveloppé dans une transaction, et rien de tout cela ne se produirait. Mais nous utilisons des services Web dans cet exemple.
Notez que les méthodes de courrier électronique et de télécopie insèrent réellement les données dans des tables de files d'attente sauvegardées dans la base de données, qui à leur tour sont gérées par un processus de tâche cron distinct. Ainsi, les appels aux méthodes de service "envoyer un e-mail" et "envoyer un fax" pourraient être annulés sans effet secondaire si nécessaire.
Une option consiste à mettre tout ce morceau de code dans le service Web lui-même, afin que le service Web lui-même appelle les méthodes de création de courrier électronique, de télécopie et de ticket dans une transaction. Mais ensuite, nous créons une méthode de service Web uniquement pour l'utilisation d'une transaction; il n'y a aucune raison valable pour laquelle nous aurions besoin d'appeler cette méthode de n'importe où, sauf ce seul script cron.
Comment gérez-vous généralement cette méthode?
la source
Réponses:
Ce que vous décrivez est en fait une transaction distribuée implémentant une validation en deux phases . Certaines plates-formes de messagerie d'entreprise incluent des gestionnaires de transactions pour prendre en charge ce genre de choses, mais les produits concrets dépendent de la plate-forme / du langage. Je n'ai pas d'expérience concrète avec de tels outils, mais j'espère que ces pointeurs vous aideront.
la source
Il est intéressant de noter que pendant que je participe à ce Q&R particulier, il y a un fil similaire sur les services prenant en charge plusieurs plates-formes sur la liste de diffusion DDD / CQRS à laquelle je participe. Je peux réitérer certains de mes conseils ici.
Une option pour prendre en charge les transactions dans un environnement hétérogène consiste à utiliser un mécanisme de transport qui prend en charge les transactions et est pris en charge sur toutes les plates-formes à partir desquelles il sera utilisé. Le protocole AMQP ( Advanced Message Queue Protocol ) prend en charge les transactions et il existe une API native pour presque toutes les langues couramment utilisées aujourd'hui. RabbitMQ est un serveur qui implémente AMQP et a été approuvé dans l'industrie comme une solution robuste.
Tirer parti d'un système basé sur RabbitMQ vous met sur la voie d'avoir un ESB complet si vous avez besoin de le développer. Vous publiez des messages sur un canal et vous abonnez à une file d'attente. Là où cela devient vraiment puissant, c'est qu'entre le canal et la file d'attente, vous pouvez effectuer beaucoup de choses intéressantes. Un canal peut alimenter plusieurs files d'attente (pub / sub) une file d'attente peut être alimentée par plusieurs canaux, vous pouvez router des messages vers différentes files d'attente en fonction du contenu, etc. etc.
Je venais de lire des alternatives aux transactions (qui viennent avec des frais généraux et transforment une opération asynchrone en une opération de blocage). RabbitMQ prend en charge ce qu'on appelle une confirmation d'éditeur . Fondamentalement, il vous permet d'enregistrer un rappel pour une méthode publiée pour gérer une transaction ayant échoué. Dans votre cas, il pourrait annuler les demandes par e-mail / fax et supprimer le ticket.
Bien sûr, le trou du lapin (pardonnez le jeu de mots) va encore plus loin à partir de là. Vous pouvez utiliser Rabbit pour effectuer des orchestrations complexes avec des services Web internes et externes.
Pour vos services Web accessibles au public, cela devient très simple. Votre service (que ce soit SOAP, REST ou JSON) publie simplement un message dans la file d'attente de service appropriée et laisse votre système interne le gérer à partir de là.
Il existe également des fonctionnalités pour créer un message de demande / réponse pour les scénarios dans lesquels vous attendez des informations rapidement.
la source
Les mots-clés que vous recherchez sont «chorégraphie de service Web».
Consultez l' article de Wikipédia à ce sujet.
la source
La façon dont j'ai géré cela dans une application de services que j'ai écrite était de créer un wrapper pour gérer les transactions nécessaires. Dans mon cas, la demande de l'utilisateur, faite par un site Web, une application de bureau ou un service Windows, devait interroger un service Web et, en fonction du résultat et des options de l'utilisateur, elle devait mettre à jour une base de données locale et, éventuellement, une base de données distante via un service Web. Ensuite, il devait générer un rapport à renvoyer immédiatement, par e-mail et / ou par fax. J'avais le contrôle sur la base de données locale, la génération d'e-mails et de rapports, mais aucune sur les services Web ou le serveur de fax.
La création d'un wrapper a permis un meilleur contrôle des transactions et une meilleure gestion des erreurs. Il a également permis une meilleure sécurité en contrôlant l'accès aux services réseau internes à partir de sources extérieures. En général, je considère le besoin de transactions et de gestion du service comme une raison valable pour créer un wrapper approprié pour une solution unique tant que le code est correctement réutilisé (pas de codage couper-coller).
la source
Tu ne peux pas.
La question que vous devriez vous poser est la suivante: comment implémenter des transactions avec le framework de service Web X? Pour l'instant, vous supposez simplement que c'est impossible.
la source