Ce qui change
Un broker livre un message au moins une fois. Si un worker valide les changements de ses handlers puis plante avant d'acquitter, le message revient et les handlers tournent deux fois : client débité en double, courriel en double. Jusqu'ici, la parade était de rendre chaque handler idempotent à la main.
Symfony 8.2 apporte la seconde moitié du pattern dont l'outbox était la première : l'inbox, qui mémorise les messages déjà traités.
Comment ça fonctionne
L'option inbox du transport écrit, dans la transaction qui exécute vos
handlers, le nom du transport et l'identifiant du message dans une table
messenger_inbox. Si le message revient, ses handlers sont ignorés et il est
acquitté.
- Un handler qui échoue annule à la fois ses changements et l'entrée d'inbox : le message pourra être retraité.
- Deux workers sur le même message : le second attend la fin de la transaction du premier.
- Un message réessayé depuis un transport d'échec est consigné sous le transport où il a échoué.
Les limites
- Il faut
symfony/doctrine-messengeret la même connexion de base que les handlers : tout repose sur une transaction commune. retentionvaut 7 jours par défaut ; elle doit dépasser le temps que votre transport peut mettre à redistribuer un message.- Les handlers par lot ne sont pas enregistrés.
- Un message
DispatchAfterCurrentBusStampdoit aller vers un transport avec outbox : l'entrée d'inbox est validée avant l'envoi, qu'un échec ferait perdre. Messenger refuse l'envoi sans outbox.
Comment s'y prendre
Créez la table, ou ajoutez-la par migration Doctrine puisqu'elle fait partie de votre schéma :
php bin/console messenger:setup-transportsSource : blog Symfony, 26 octobre 2026. Source en anglais.