Le pattern "Transactional Outbox" vise à résoudre le problème de la double écriture entre une base de données relationnelle et un système de messagerie comme RabbitMQ dans les applications événementielles Symfony. Ce problème survient lorsque la persistance des données dans la base de données et l'envoi d'un événement correspondant à un autre système ne sont pas atomiques, entraînant des incohérences si l'un des deux processus échoue.
Ce pattern garantit l'atomicité en écrivant l'événement dans une table dédiée de la base de données, la table "outbox_message", au sein de la même transaction que les données métier. Ainsi, soit les données métier et l'enregistrement de l'événement sont persistés ensemble, soit aucun des deux n'est enregistré.
Un processus séparé, l'"Outbox Relay", est ensuite responsable de lire les messages non publiés de cette table, de les envoyer à RabbitMQ, puis de marquer ces messages comme publiés. Cette approche garantit qu'un événement est soit bien enregistré dans la base de données et envoyé au système de messagerie, soit ni l'un ni l'autre, résolvant ainsi les échecs critiques qui pourraient survenir entre les deux écritures indépendantes.
Le pattern Transactional Outbox est présenté comme une solution élégante pour synchroniser une base de données PostgreSQL et un message broker comme RabbitMQ, évitant les problèmes des transactions distribuées (2PC). Contrairement à l'approche classique qui risque de publier un message sans que la transaction SQL ne soit validée, ce pattern repose sur l'écriture d'un événement dans une table dédiée au sein de la base de données, garantissant ainsi l'atomicité. Un job asynchrone se charge ensuite de publier le message dans RabbitMQ une fois la transaction principale réussie.
L'auteur souligne les limites des transactions distribuées (2PC), notamment l'absence de support XA pour RabbitMQ, les pénalités de performance et la dégradation de la disponibilité globale du système. Le pattern Transactional Outbox contourne ces problèmes en centralisant la fiabilité sur la base de données, simplifiant ainsi l'architecture tout en maintenant la cohérence des données.
La mise en œuvre pratique implique une transaction unique pour sauvegarder l'entité et l'événement dans la base, suivie d'un processus asynchrone pour publier le message. L'utilisation d'un verrou distribué (SchedulerLock) permet d'éviter les doublons dans un environnement multi-instances, offrant une solution robuste et performante pour les systèmes distribués.
Tout est dans le titre
Cet article montre la mise en place d'une architecture pilotée par les événements. La technologie pour la démonstration est Symfony / RabbitMQ.
Tout est dans le titre
Tout est dans le titre
Tout est dans le titre
Tout est dans le titre
Les slides des conférences données par Zwindler :
1- SREs ! SREs partout !
2- Du code Terraform vraiment factorisé avec Terragrunt
3- Ciel ! Mon Kubernetes mine des Bitcoins
4- 101 ways to break your RabbitMQ cluster
5- Le (logiciel) libre a-t-il de beaux jours devant lui ?
6- Besoin de métriques Prometheus à long terme ? Thanos fera des Marvels !
7- Dans ton Kube : retour sur 2 ans d’incidents en production
8- Ami développeur, deviens un Ops sans effort avec Ansible
Tout est dans le titre
Tout est dans le titre
Tout est dans le titre
Tout est dans le titre
Une présentation intéressante de cette architecture et des solutions disponibles dont RabbitMQ et Kafka
Tout est dans le titre
Tout est dans le titre
Tout est dans le titre
Tout est dans le titre
Tout est dans le titre
Des liens vers les slides des conférences : du Symfony, du React, de l'Elasticsearch, du Doctrine, du HTTP, du RabbitMQ et du TDD