Le véritable problème consiste à coordonner l’événement avec la commande
Lorsqu’un client termine son achat, le service de commandes doit modifier sa base de données et prévenir le stock, la facturation, les emails, l’analytique ou la détection de fraude. L’implémentation évidente effectue deux écritures indépendantes : enregistrer la commande puis publier un message. Cet intervalle crée le risque de double écriture. Si la base confirme mais que le broker ne reçoit rien, la commande existe sans déclencher les traitements aval. Si le message part d’abord et que l’enregistrement échoue, les consommateurs réagissent à une commande inexistante.
Une transaction distribuée pourrait coordonner plusieurs ressources, mais elle est souvent indisponible, indésirable ou non prise en charge par toute la chaîne. L’outbox transactionnelle limite la frontière atomique à une seule base. Dans la transaction locale qui crée ou modifie la commande, l’application insère aussi une ligne décrivant l’événement. Un relais distinct l’achemine ensuite. L’état métier et l’intention de publier deviennent donc visibles ensemble ou ne le deviennent pas.
Traiter l’outbox comme un contrat opérationnel
La table outbox n’est pas un dossier temporaire sans structure. Chaque ligne devrait contenir un identifiant d’événement stable, son type, l’identifiant de l’agrégat, une version ou séquence, la date de création et le minimum de données utiles. L’agrégat peut être une commande, un paiement ou une réservation de stock. Une clé telle que order_id permet de conserver l’ordre relatif des événements de la même entité lorsque le transport le permet.
Le payload ne doit pas recopier toutes les colonnes. Un événement décrit un fait métier déjà accompli, au moyen d’un contrat versionnable qui exclut secrets, jetons de paiement et données personnelles inutiles. Des en-têtes techniques peuvent porter la corrélation et le traçage, mais le schéma doit rester compréhensible par les consommateurs. Propriété, compatibilité, classification des données et évolution se définissent avant le premier abonnement.
Une seule transaction locale pour l’état et l’événement
L’insertion dans l’outbox doit participer au même commit que la modification métier. Enregistrer la commande, confirmer puis ouvrir une seconde transaction pour l’événement recrée précisément la fenêtre que le pattern élimine. Les frameworks qui accumulent des événements en mémoire doivent les vider dans l’outbox au sein de la transaction courante et faire échouer le commit si cette écriture est impossible.
Choisir un relais par interrogation ou la capture des changements
Un relais par interrogation périodique sélectionne les lignes non traitées, envoie les messages et enregistre sa progression. Il est explicite, portable et simple à raisonner, mais demande une gestion attentive de la concurrence et des verrous. Avec PostgreSQL, plusieurs processus de traitement peuvent sélectionner des lots déterministes et utiliser FOR UPDATE SKIP LOCKED pour éviter les lignes détenues par un autre processus. Cette méthode facilite un usage de type file, sans garantir l’équité ni remplacer une politique de réessai.
La capture des changements, ou CDC, lit les modifications validées dans le journal de la base. Un connecteur observe les insertions dans l’outbox et les transforme en événements dirigés vers les flux appropriés. Debezium documente un Outbox Event Router qui utilise notamment identifiant d’agrégat, type d’événement et payload pour construire le message. La CDC élimine l’interrogation applicative, mais ajoute connecteurs, offsets, permissions et procédures de reprise.
Retenir le modèle que l’équipe sait exploiter
L’interrogation périodique convient souvent à des volumes maîtrisés et à une équipe qui souhaite posséder un petit relais dans son environnement d’exécution. La CDC convient mieux quand une plateforme de diffusion d’événements existe déjà et que le journal de la base est géré comme une infrastructure de production. Les deux modèles exigent des mesures de délai entre commit et publication, de backlog, d’erreurs et de capacité de reprise. La technologie ne garantit pas la cohérence à elle seule ; la transaction locale et les invariants vérifiés le font.
Assumer une livraison au moins une fois et rendre les traitements idempotents
Le relais peut s’arrêter après la publication mais avant d’enregistrer le traitement de la ligne. Au redémarrage, il renvoie l’événement. Les doublons sont donc normaux dans une pipeline avec livraison au moins une fois. L’outbox ne permet pas de promettre un traitement unique de bout en bout : relais, broker, consommateur et système externe possèdent chacun une frontière d’acquittement.
Chaque consommateur doit reconnaître l’identifiant d’événement. Une inbox locale ou une table de déduplication peut le mémoriser dans la même transaction que l’effet métier. S’il existe déjà, le consommateur acquitte sans répéter la modification. Les effets externes, comme un appel à un prestataire de paiement, demandent aussi une clé d’idempotence acceptée par le destinataire et une réconciliation indépendante. Les traces de déduplication doivent vivre au moins autant que la fenêtre réaliste de réessai et de rejeu.
Préserver l’ordre par agrégat plutôt que globalement
La plupart des parcours imposent que OrderCreated précède OrderCancelled pour une même commande, pas que tous les événements du magasin soient sérialisés. Une séquence monotone par agrégat, une clé de partition cohérente et un consommateur qui rejette ou met en quarantaine les versions désordonnées rendent la règle testable. Un ordre global réduit le parallélisme sans correspondre, le plus souvent, à un invariant métier.
Gouverner les réessais, la rétention et la quarantaine
Le relais doit distinguer une panne transitoire d’un enregistrement impossible à publier. Les erreurs transitoires suivent des réessais limités avec attente progressive et jitter. Les données invalides passent en quarantaine avec une raison, un payload protégé et une procédure de correction. Réessayer indéfiniment un message mal formé peut bloquer le lot ou consommer la capacité ; une voie séparée maintient le flux sain sans effacer les preuves.
La rétention équilibre audit, rejeu et coût de stockage. Supprimer immédiatement les lignes publiées complique l’analyse d’un incident ; tout conserver dégrade index et requêtes. Il vaut mieux archiver ou partitionner selon une politique explicite et garder les identifiants nécessaires à la déduplication. Un rejeu doit être autorisé, borné par une plage et observable, car il peut répéter des effets métier même lorsque le transport fonctionne comme prévu.
Observer la distance entre le commit et sa conséquence
Les signaux principaux sont l’âge de la plus ancienne ligne non publiée, la profondeur du backlog, la latence du commit à l’envoi, le débit de publication, les réessais, les quarantaines et les doublons détectés. Il faut les segmenter par type d’événement et agrégat critique. Une petite file peut encore cacher une commande bloquée ; distributions et âge maximal complètent donc les totaux.
Journaux et traces relient event_id, aggregate_id, commit, tentative du relais et consommation sans exposer de payload sensible. Les alertes décrivent l’impact métier : commandes confirmées sans réservation, factures retardées ou messages client absents. Tableaux de bord et procédures indiquent qui peut suspendre le relais, rejouer un événement ou libérer une quarantaine.
Tester les interruptions à chaque frontière délicate
Les tests décisifs arrêtent les processus avant le commit, après le commit mais avant la lecture, après la publication mais avant l’acquittement et pendant l’effet du consommateur. Après chaque reprise, on vérifie qu’aucun événement ne manque, que les doublons restent inoffensifs et que l’ordre par agrégat demeure correct. Il faut aussi simuler l’indisponibilité du broker, la croissance du backlog, des lignes invalides et la perte temporaire du connecteur CDC.
Le déploiement peut commencer par une observation en parallèle, un nombre limité de types d’événement et une réconciliation entre commandes et effets aval. Un contrôle périodique cherche les commandes sans outbox, les lignes trop anciennes et les conséquences absentes. Pour rendre ce modèle exploitable dans le checkout, le stock et les automatisations, découvrez nos services ecommerce et systèmes ou échangez avec notre équipe. Le but n’est pas de promettre zéro doublon, mais de rendre chaque état récupérable et chaque divergence visible.
Questions fréquentes
Pourquoi une double écriture entre base et courtier de messages est-elle risquée ?
Les deux systèmes peuvent acquitter à des moments différents : un arrêt brutal laisse alors une commande validée sans événement, ou un événement pour une modification non validée. L’outbox réunit les écritures dans une même validation transactionnelle locale.
L’outbox transactionnelle garantit-elle un traitement unique de bout en bout ?
Non. Le relais peut republier après un arrêt brutal et les acquittements traversent plusieurs systèmes. L’architecture suppose une livraison au moins une fois et rend les consommateurs idempotents grâce à l’identifiant d’événement, au journal de réception ou à la déduplication.
Faut-il publier l’outbox par interrogation périodique ou par CDC ?
Choisissez le modèle que l’équipe sait exploiter. L’interrogation est explicite et portable ; la CDC lit le journal et impose la gestion des connecteurs et des positions de lecture. Tous deux nécessitent le suivi du retard et de l’accumulation.
Comment préserver l’ordre des événements ecommerce ?
Utilisez une séquence par agrégat, une clé de partition cohérente et un consommateur qui valide les versions. L’ordre concerne généralement une commande ou un paiement, pas tout le magasin.
Articles connexes
Files asynchrones e-commerce : backpressure, DLQ et rejeu contrôlé
Séparer la confirmation de commande des effets différés et gouverner workers, nouvelles tentatives, dead-letter queues et rejeu sans masquer les échecs.
Webhooks e-commerce fiables : idempotence, réessais et observabilité
Un plan de mise en œuvre pour recevoir les événements de commande et de paiement, éviter les effets répétés, récupérer les erreurs et mesurer toute la chaîne.
Éviter la survente e-commerce grâce aux réservations et au contrôle des accès concurrents
Une méthode opérationnelle pour distinguer les états du stock, attribuer la dernière unité de manière atomique et résorber les écarts entre canaux de vente.
