Aller au contenu

Corrections

Quand une affirmation se révèle fausse, trop absolue ou dépassée, le texte est corrigé et la correction est inscrite ici et en bas du texte. Les reprises de style n'y figurent pas. Comment signaler une erreur.

  1. ALTER TABLE sans panne : la file de verrous

    Le changement de type ne réécrit pas la table quand l'ancien type est binaire compatible avec le nouveau (varchar vers text) ; l'ajout de clé étrangère prend un verrou SHARE ROW EXCLUSIVE, qui bloque les écritures mais pas les lectures, sur les deux tables.

  2. Chiffrement applicatif et gestion de clés

    La rotation de la KEK n'impose pas de ré-envelopper toutes les DEK : un KMS géré garde les anciennes versions et déchiffre avec la bonne ; le ré-enveloppement sert à retirer une version, de préférence par rechiffrement interne au KMS.

  3. Chiffrement applicatif et gestion de clés

    Une clé unique n'est pas « impossible à tourner » : elle impose de tout rechiffrer. L'injection SQL n'est couverte que si le résultat injecté ne passe pas par le déchiffrement applicatif.

  4. Choisir l'ennui : le budget d'innovation d'une équipe

    Le débit d'une file dans PostgreSQL était donné sans condition ; il dépend du matériel, de la taille des messages et de la conception, et le gonflement vient des transactions longues qui empêchent le vacuum de récupérer les lignes mortes.

  5. Circuit breakers : pourquoi ils déçoivent

    La limite de concurrence en PHP libérait ses emplacements dans un finally, qui ne s'exécute pas quand le processus meurt (erreur fatale, worker tué) ; l'article précise que chaque emplacement doit expirer seul. Le timeout par défaut cité (trente secondes) est remplacé par la valeur réelle de default_socket_timeout en PHP, 60 s.

  6. CQRS et UX : ce que coûte l'eventual consistency

    Le token renvoyé est la position globale de l'événement, pas sa version ; et comparer cette position à celle de la projection ne garantit la lecture de sa propre écriture que si la projection ne saute aucune position, une séquence PostgreSQL n'ordonnant pas les commits. L'article donne désormais la condition et les deux parades.

  7. CQRS et UX : ce que coûte l'eventual consistency

    Une projection n'est pas asynchrone par nature : elle peut s'exécuter dans la transaction de la commande (mode par défaut d'Ecotone), et le retard ne concerne que les projections rendues asynchrones.

  8. Durable execution : moteur de workflow ou table d'état ?

    Une erreur de non-déterminisme ne fait pas échouer l'instance par défaut (Temporal) : elle se bloque, sa tâche est retentée, et l'erreur n'apparaît qu'au réveil de l'instance, pas au déploiement.

  9. Durable execution : moteur de workflow ou table d'état ?

    Migrer une instance d'un moteur ne passe pas seulement par terminer et redémarrer : un reset à un point antérieur de l'historique est possible et réexécute les activités qui suivent.

  10. Event Sourcing : quand il faut refuser le pattern

    L'eventual consistency était présentée comme inhérente à l'Event Sourcing ; elle vient des projections asynchrones, une projection synchrone dans la même transaction (mode par défaut d'Ecotone) l'évite.

  11. Event Sourcing : quand il faut refuser le pattern

    L'audit trail était présenté comme complet ; un log d'événements ne trace que les écritures, pas les lectures que visent par exemple les contrôles d'audit HIPAA, et n'est pas infalsifiable par construction.

  12. Event Sourcing : quand il faut refuser le pattern

    La durée de rebuild sur 50 millions d'événements était donnée sans condition ; elle est désormais calculée à partir d'un débit posé.

  13. Event Sourcing : quand il faut refuser le pattern

    L'extrait loadAtVersion utilisait des variables non définies (streamName, aggregate) ; il est corrigé.

  14. Event Sourcing : quand il faut refuser le pattern

    Les sagas étaient présentées comme douloureuses hors Event Sourcing ; elles réagissent à des événements qu'un système mutable peut aussi émettre (par une outbox), Event Sourcing en retire seulement une étape.

  15. GDPR et Event Sourcing : effacer sans supprimer l'histoire

    Le crypto-shredding était présenté comme « largement accepté » et équivalent à un effacement : le RGPD traite les données pseudonymisées comme personnelles, et la destruction de clé ne vaut effacement que si plus rien ne permet d'identifier la personne (clé absente des sauvegardes, destruction vérifiable).

  16. GDPR et Event Sourcing : effacer sans supprimer l'histoire

    Après suppression dans le PDS, les événements restants ne sont pas anonymes tant qu'un identifiant du stream peut être relié à la personne ailleurs ; la minimisation et la limitation de la conservation sont distinguées, et l'exception d'obligation légale à l'effacement est rappelée.

  17. Iceberg pour une équipe de dix

    Le texte affirmait qu'un pointeur sur stockage objet ne peut pas arbitrer deux écrivains ; un stockage qui accepte l'écriture conditionnelle (If-Match, If-None-Match) le permet, mais tous les fournisseurs compatibles S3 ne l'offrent pas.

  18. Idempotency keys : les sept détails qui comptent

    L'attente de l'INSERT … ON CONFLICT DO NOTHING concurrent vaut en READ COMMITTED ; en REPEATABLE READ ou SERIALIZABLE, le second INSERT échoue avec une erreur de sérialisation.

  19. Idempotency keys : les sept détails qui comptent

    Le prestataire ne reconnaît une clé rejouée que pendant sa durée de conservation (Stripe peut la purger après 24 heures) ; Stripe mémorise aussi ses erreurs 500.

  20. Isolation multi-tenant : comment les fuites entre clients arrivent

    Un cache HTTP partagé ne confond pas les tenants quand le tenant passe par Authorization (la norme l'interdit sauf public, s-maxage ou must-revalidate) ou par un header listé dans Vary ; le risque vaut pour un cookie ou un header hors de Vary.

  21. Isolation multi-tenant : comment les fuites entre clients arrivent

    Next.js refuse headers() et cookies() dans une fonction en cache ; la fuite par mémoïsation passe par un tenant lu hors des arguments (variable de module, contexte asynchrone, closure).

  22. Kill the Aggregate : et si la frontière de cohérence n'était pas l'entité ?

    Dix utilisateurs qui modifient chacun leur panier n'écrivent pas dans le même stream ; le conflit suppose un panier partagé ou des écritures concurrentes sur le même panier.

  23. Kill the Aggregate : et si la frontière de cohérence n'était pas l'entité ?

    Le mécanisme DCB était décrit avec des streams et une condition arbitraire évaluée par le store ; la spécification repose sur une requête (types et étiquettes) et une condition « aucun événement correspondant après la position lue », la règle métier restant dans l'application.

  24. Kill the Aggregate : et si la frontière de cohérence n'était pas l'entité ?

    EventStoreDB n'est pas recensé parmi les stores supportant DCB ; Axon Server et Axon Framework 5 le sont.

  25. Kill the Aggregate : et si la frontière de cohérence n'était pas l'entité ?

    La critique « Kill the Aggregate » était présentée comme visant l'aggregate qui coordonne des processus longs ; elle vise la frontière de cohérence fixée à la conception, qui oblige à choisir entre un aggregate trop large et une saga pour les règles qui traversent plusieurs entités. Une projection asynchrone ne peut pas non plus faire respecter un plafond d'articles.

  26. Le retry qui a tué la production

    Le texte affirmait qu'un 503 implique que la requête n'a pas été exécutée et qu'un 404 ou un refus d'autorisation ne se rejoue jamais ; le 503 l'indique sans le garantir pour une méthode non idempotente, et les exceptions (jeton expiré, réplique en retard) sont précisées.

  27. Le retry qui a tué la production

    APCu partage sa mémoire entre les workers d'un même master PHP-FPM, pas de toute la machine, et le compteur doit y être mis à jour par des opérations atomiques.

  28. Ne branchez pas vos effets de bord sur les domain events

    L'Outbox livre au moins une fois, pas exactement une fois : un mail peut partir deux fois si le poller s'arrête entre l'envoi et le marquage. Le texte affirmait qu'aucun événement persisté ne laisse un mail non envoyé et qu'aucun ne part en double.

  29. Ne branchez pas vos effets de bord sur les domain events

    Le SagaManager peut dédupliquer la commande, pas garantir qu'un mail externe n'est envoyé qu'une fois ; il faut une clé d'idempotence côté fournisseur ou accepter un doublon rare.

  30. Ne branchez pas vos effets de bord sur les domain events

    Ni l'Outbox ni la saga ne règlent à eux seuls le décalage entre le mail et la projection (problème 1) ; le texte le présentait implicitement comme résolu.

  31. Ne branchez pas vos effets de bord sur les domain events

    Une saga ou un routage branchés sur le bus en mémoire perdent l'événement au même titre que le mail si le processus s'arrête après l'append ; ils ne sont sûrs que s'ils lisent le store depuis une position persistée.

  32. Ne branchez pas vos effets de bord sur les domain events

    L'arbre de décision validait sans condition un subscriber direct pour une projection ; une projection persistée perd l'événement de la même façon, sauf si elle est mise à jour dans la transaction de l'append ou reprend à une position persistée.

  33. Ne branchez pas vos effets de bord sur les domain events

    Le mail arrivé avant la projection était décrit comme l'incohérence que CQRS devait éviter ; c'est l'eventual consistency d'une projection asynchrone, que CQRS ne supprime pas.

  34. Optimistic locking : éviter le Lost Update silencieux

    L'extrait `SELECT MAX(event_version) ... FOR UPDATE` est refusé par PostgreSQL (verrou interdit avec un agrégat), et un verrou sur la dernière ligne d'événement ne fait pas voir à la seconde transaction la ligne insérée par la première en READ COMMITTED. La contrainte d'unicité est la vraie garantie ; le verrou utile porte sur une ligne de version mise à jour à chaque append.

  35. Optimistic locking : éviter le Lost Update silencieux

    Sans garde de version, B n'écrase pas A : les deux événements sont ajoutés et l'invariant est violé ; la phrase est corrigée.

  36. Optimistic locking : éviter le Lost Update silencieux

    Le schéma de la course « sans protection » affichait un conflit sur la version 6 ; sans garde, l'append de B est accepté en version 7 et rien ne signale l'erreur.

  37. Outbox Pattern : pourquoi votre EventBus ne suffit pas

    L'inbox ne rend un doublon sans effet que si son insertion et l'effet du traitement sont commités ensemble ; pour un mail ou un appel à une API externe, il faut une clé d'idempotence. Le texte laissait croire l'inverse.

  38. Outbox Pattern : pourquoi votre EventBus ne suffit pas

    Ajout de deux conditions omises : plusieurs pollers en SKIP LOCKED ne préservent pas l'ordre de publication, et le slot de réplication du CDC retient le WAL tant que Debezium ne l'a pas consommé.

  39. Projection rebuild : ce qui casse à 50 millions d'événements

    Le Lazy Backfill comparait la position de la ligne à la position globale du store, ce qui marque presque toutes les lignes en retard et ne détecte pas une ligne calculée par l'ancien code : il faut une version de projection par ligne et la dernière position du flux de l'aggregate.

  40. Projection rebuild : ce qui casse à 50 millions d'événements

    CREATE OR REPLACE VIEW échoue si la nouvelle table change le nom, le type ou l'ordre des colonnes ; la bascule prend un verrou ACCESS EXCLUSIVE, et le rollback suppose que l'ancienne table a continué d'être alimentée.

  41. Projection rebuild : ce qui casse à 50 millions d'événements

    Ajout de la condition sur la pagination par position (trous de séquence pendant le rattrapage), correction de l'arithmétique du checkpoint (cinquante fois, pas dix) et de la hot partition, qui tient à quelques aggregates très chargés, pas à une répartition 80/20 que le hachage disperse.

  42. Saga ou process manager : où vit l'état du workflow

    La saga originelle était dite sans état ; dans le papier de 1987, un composant d'exécution journalise chaque étape pour savoir quoi compenser après un crash, et prévoit aussi une reprise en avant.

  43. Saga ou process manager : où vit l'état du workflow

    Le SagaManager était dit garantir un traitement unique ; le schéma vérifier, dispatcher, marquer laisse passer un doublon après un crash ou en cas de livraisons concurrentes. Ajout de l'outbox, de la contrainte d'unicité et des handlers idempotents.

  44. Saga ou process manager : où vit l'état du workflow

    Le timeout était dit déclencher une compensation propre ; FailTransfer seul ne rembourse pas un débit déjà passé, et un timeout tardif doit être ignoré.

  45. Saga ou process manager : où vit l'état du workflow

    Temporal était décrit sans sa contrainte principale : le code de workflow est rejoué et doit rester déterministe.

  46. Saga ou process manager : où vit l'état du workflow

    Le tableau décrivait la saga originelle comme déclenchée par une chaîne d'événements ; dans le papier de 1987, sa séquence d'étapes est fixée d'avance et exécutée par le SGBD.

  47. Sagas : la compensation que personne ne teste

    L'extrait de pierre tombale laissait une course entre la réservation et son annulation concurrentes, qui pouvaient aboutir toutes les deux ; ajout de la sérialisation sur operationId par un upsert PostgreSQL.

  48. Sagas : la compensation que personne ne teste

    « Personne n'a vu l'état intermédiaire » après un ROLLBACK suppose que les lectures non validées sont interdites ; la condition est écrite.

  49. Sagas : la compensation que personne ne teste

    Le texte demandait exactement un pivot par saga ; une saga entièrement compensable n'en a pas, la règle est « au plus un ».

  50. Schema evolution : corriger sans réécrire l'histoire

    Le rollback d'un upcaster n'est trivial que tant qu'aucun événement n'a été écrit au nouveau format : l'ancien code ne sait pas lire les événements v2. Le texte présentait le rollback comme trivial sans condition.

  51. Schema evolution : corriger sans réécrire l'histoire

    L'exemple d'upcaster remplaçait un montant absent par 0 (un retrait effacé en silence) et mélangeait les deux migrations de la chaîne ; il est scindé en v1→v2 et v2→v3, et un montant illisible lève une erreur.

  52. Schema evolution : corriger sans réécrire l'histoire

    « L'ancien stream ne se supprime jamais » est conditionné : un effacement imposé par le RGPD peut l'exiger si les événements portent des données personnelles.

  53. Schema evolution : corriger sans réécrire l'histoire

    Un échantillon de 1 000 payloads était présenté comme filet de sécurité avant migration sans réserve ; il peut manquer une forme rare, que seul un passage sur tous les événements du type trouve à coup sûr.

  54. Systèmes event-sourcés · Anti-patterns experts

    Kafka était dit offrir l'exactly-once « pour les consumers » ; cette sémantique couvre les traitements qui lisent et écrivent dans Kafka avec des transactions, et exige la coopération du système cible au-delà.

  55. Systèmes event-sourcés · Anti-patterns experts

    La règle « un aggregate aussi petit que possible » était attribuée à Greg Young ; elle vient de Vaughn Vernon (Effective Aggregate Design, 2011).

  56. Systèmes event-sourcés · Anti-patterns experts

    Le SyncEventBus était décrit comme traitant les projections dans la transaction de la commande, ce qui contredit le chapitre 7 (fire-and-forget) ; l'anti-pattern décrit est désormais celui des projections toutes synchrones, avec le cas où il reste défendable.

  57. Systèmes event-sourcés · Anti-patterns experts

    Le read model d'exemple stockait une date relative (« il y a 3 jours ») qui devient fausse sans nouvel événement ; il stocke la date et calcule le libellé à l'affichage.

  58. Systèmes event-sourcés · Anti-patterns experts

    Une position sur les sagas était attribuée à Udi Dahan sans source ; elle est retirée et le critère est assumé par l'auteur.

  59. Systèmes event-sourcés · Anti-patterns experts

    La saga « bien conçue » compensait au timeout tant que le virement n'était pas complété, ce qui reproduit la saga zombie du chapitre 6 si le crédit aboutit après ; le crédit porte désormais une échéance vérifiée par le compte destination, et le texte renvoie au chapitre 6.

  60. Systèmes event-sourcés · Anti-patterns experts

    Le token de read-your-own-writes par version de stream ne vaut que pour une projection construite depuis ce même stream ; sinon c'est la position globale comparée au checkpoint, comme au chapitre 3.

  61. Systèmes event-sourcés · Anti-patterns experts

    Un événement de domaine était dit modifiable « librement » ; il évolue sans coordination externe, mais l'historique persisté passe par l'upcasting (chapitre 11). Ajouter un champ optionnel à l'enveloppe ne touche pas les événements existants ; c'est un champ rendu obligatoire ou un changement de type qui le fait.

  62. Systèmes event-sourcés · Anti-patterns experts

    La saga corrigée compensait encore au timeout sur la seule absence de TransferCredited ; l'échéance empêche un crédit tardif, pas la livraison tardive d'un crédit accepté avant elle. Le timeout demande désormais l'issue définitive à la destination et ne compense que sur CreditExpired.

  63. Systèmes event-sourcés · Anti-patterns experts

    Un EventStore était dit incapable de subscriptions et de consumer groups ; c'est vrai d'un store sur table PostgreSQL, pas de stores dédiés comme KurrentDB. L'anti-pattern est recentré sur la lecture du log par d'autres services, et non sur la lecture par position, qui est celle des projections.

  64. Systèmes event-sourcés · Anti-patterns experts

    Un stream de quelques centaines d'événements était présenté comme signe d'aggregate trop large ; un compte ancien en a légitimement des milliers, la parade y est la clôture périodique du stream. Ajout des conditions manquantes : la déduplication en mémoire ne survit pas à un redémarrage, la publication après commit sans outbox peut se perdre, et le tenantId d'un store multi-tenant appartient à l'enveloppe système.

  65. Systèmes event-sourcés · Au-delà des Aggregates

    La thèse « Kill Aggregate » de Sara Pellegrini était présentée comme un modèle append puis validation asynchrone et compensation ; elle a débouché sur les Dynamic Consistency Boundaries, qui gardent un contrôle optimiste. Le modèle asynchrone est désormais présenté comme une autre réponse.

  66. Systèmes event-sourcés · Au-delà des Aggregates

    Une citation de Greg Young (« les aggregates ont été une erreur », 2016) et deux autres propos qui lui étaient prêtés n'ont pas de source vérifiable ; ils sont retirés.

  67. Systèmes event-sourcés · Au-delà des Aggregates

    Temporal : les activités ne sont pas garanties exécutées une seule fois (seulement observées terminées une fois) et doivent être idempotentes ; waitForSignal() n'existe pas dans le SDK TypeScript (condition()), qui remplace Math.random() et Date.now() par des versions déterministes.

  68. Systèmes event-sourcés · Au-delà des Aggregates

    AI Act : la traçabilité relève de l'article 12 (journalisation), pas des articles 13 et 14 ; l'assurance à haut risque se limite à la vie et à la maladie, et le crédit exclut la détection de fraude. Bâle III, sans rapport, est retiré.

  69. Systèmes event-sourcés · Au-delà des Aggregates

    Un acteur était dit éliminer tout conflit de concurrence ; cela suppose une activation unique, et Orleans garde un contrôle de version (InconsistentStateException). Les frameworks d'agents étaient dits converger vers un EventStore ; LangGraph, par exemple, persiste par checkpoints.

  70. Systèmes event-sourcés · Au-delà des Aggregates

    « Un virement débité mais jamais crédité » illustrait un invariant qui justifie un aggregate ; il traverse deux aggregates et relève de la saga (chapitre 6). L'exemple est remplacé par un retrait au-delà du découvert autorisé.

  71. Systèmes event-sourcés · Au-delà des Aggregates

    Temporal était dit ne pas concurrencer les sagas maison ; il les remplace, et c'est l'EventStore qu'il ne remplace pas. L'origine du modèle acteur est précisée : formalisé par Carl Hewitt en 1973, Erlang conçu à partir de 1986.

  72. Systèmes event-sourcés · Au-delà des Aggregates

    Les Dynamic Consistency Boundaries étaient présentées sans la condition d'atomicité : sur PostgreSQL en READ COMMITTED, vérifier la condition puis insérer laisse passer deux réservations concurrentes de la dernière place. Le texte indique les deux parades (sérialiser les appends qui se recouvrent, ou SERIALIZABLE avec rejeu). L'exemple, qui annonçait des critères de lecture et d'append différents en montrant les mêmes, lit désormais avec une position et n'est bloqué que par un nouveau SeatBooked.

  73. Systèmes event-sourcés · Au-delà des Aggregates

    Un jeu d'évaluation figé par position dans le log ignorait les commits hors ordre décrits au chapitre 5 ; il faut couper sous une position stable. Ajout du mode de défaillance propre à Temporal : un changement de code de workflow casse le rejeu des exécutions en cours sans versioning (patched).

  74. Systèmes event-sourcés · Avant-propos

    Le regret public attribué à Greg Young sur Event Sourcing « recommandation par défaut » n'a pas de source vérifiable ; la position est désormais celle de l'auteur. Les CQRS Documents font une cinquantaine de pages, pas 40.

  75. Systèmes event-sourcés · Avant-propos

    Une obligation d'audit trail se remplit aussi avec un journal d'audit ; elle justifie Event Sourcing sans l'imposer. L'état mutable ne cause pas d'états incohérents après panne quand les écritures sont transactionnelles.

  76. Systèmes event-sourcés · Avant-propos

    Le plan annoncé plaçait l'évolution de schéma et le RGPD en partie 3 ; ils sont en partie 4 (niveau expert), la partie 3 couvrant les tests, le passage en production et le scaling.

  77. Systèmes event-sourcés · Checklist de mise en production

    La contrainte d'unicité sur (stream_name, event_version) crée elle-même l'index qui sert aux chargements par stream ; un second index sur les mêmes colonnes est redondant.

  78. Systèmes event-sourcés · Checklist de mise en production

    Le tri par global_position rend un rebuild déterministe, mais une projection qui lit en direct au-delà de son checkpoint peut sauter un événement validé en retard : la séquence suit l'ordre d'allocation, pas l'ordre de commit.

  79. Systèmes event-sourcés · Checklist de mise en production

    La déduplication par eventId ne protège d'un doublon que si la trace de l'eventId est écrite dans la même transaction que le read model ou l'état de la saga.

  80. Systèmes event-sourcés · Checklist de mise en production

    La double écriture d'un événement sous deux formats dans l'EventStore ferait compter deux fois le même fait par les projections ; elle ne vaut que pour les integration events publiés à l'extérieur, l'EventStore passant par l'upcasting.

  81. Systèmes event-sourcés · Checklist de mise en production

    Le RGPD ne demande pas seulement l'effacement « dans les meilleurs délais » (article 17) : l'article 12 impose d'informer la personne des mesures prises dans un délai d'un mois, prolongeable de deux mois.

  82. Systèmes event-sourcés · Checklist de mise en production

    Un rollback vers une version qui ignore un nouveau type d'événement n'est sans risque que pour les projections ; un aggregate qui ignore un événement de son stream reconstruit un état faux. Le nouveau type ne s'émet qu'après un déploiement qui sait le lire.

  83. Systèmes event-sourcés · Checklist de mise en production

    La sérialisation des écritures par advisory lock ne règle les commits hors ordre qu'avec une séquence en CACHE 1 ; la lecture sous le xmin du snapshot, décrite au chapitre 5, est ajoutée comme troisième parade.

  84. Systèmes event-sourcés · Conclusion

    Une table temporelle (SQL Server, MariaDB) donne aussi l'état d'un compte à une date ; ce que seul le log d'événements donne directement, c'est la suite des faits et leur cause.

  85. Systèmes event-sourcés · Conclusion

    globalPosition donne un ordre total sur les événements stockés, dans l'ordre d'allocation de la séquence et non dans l'ordre de commit ; une lecture en direct doit gérer les transactions validées en retard.

  86. Systèmes event-sourcés · Conclusion

    La chaîne correlationId/causationId relie les commandes et les événements émis, pas les mises à jour des projections, qui n'émettent pas d'événement ; elle n'est complète que si chaque handler propage les deux identifiants.

  87. Systèmes event-sourcés · Conclusion

    Rejouer un stream jusqu'à une date donne l'état interprété par le code actuel, en date d'enregistrement ; il peut différer de l'état affiché à l'époque si la logique a changé, et une donnée crypto-shreddée ne revient pas.

  88. Systèmes event-sourcés · Conclusion

    Un checkpoint de projection au-delà d'une globalPosition ne prouve pas que l'événement a été appliqué (Dead Letter Queue, événement validé en retard et sauté).

  89. Systèmes event-sourcés · Conclusion

    Temporal ne dispense pas d'écrire les compensations : il garantit leur exécution malgré une panne de worker ; il impose en contrepartie un code de workflow déterministe et versionné.

  90. Systèmes event-sourcés · CQRS : séparer écriture et lecture

    Une vue SQL sait calculer un cumul entre lignes (fonction de fenêtre) et se recalcule aussi ; ce qu'elle ne peut pas retrouver, c'est l'historique que les UPDATE ont écrasé. Une vue matérialisée n'est pas toujours à jour : elle attend un REFRESH explicite.

  91. Systèmes event-sourcés · CQRS : séparer écriture et lecture

    Le QueryBus n'empêche pas un query handler d'écrire : la lecture seule est une convention tant qu'un rôle ou une transaction READ ONLY ne l'impose pas.

  92. Systèmes event-sourcés · CQRS : séparer écriture et lecture

    Le chemin d'écriture se réplique aussi : l'optimistic locking ne sérialise que les écritures concurrentes sur un même stream. Des projections en mémoire répliquées peuvent répondre à des positions différentes.

  93. Systèmes event-sourcés · CQRS : séparer écriture et lecture

    Le token de read-your-own-writes est la position de l'événement écrit, comparée au checkpoint de la projection ; la version d'un stream de virement ne dit rien de l'état du compte, et le token ne couvre pas les événements émis ensuite par une saga.

  94. Systèmes event-sourcés · CQRS : séparer écriture et lecture

    L'eventual consistency ne borne pas le délai de convergence ; un bus synchrone dans le processus met la projection à jour avant la réponse, et la perte d'événement sans outbox concerne une projection alimentée par un bus publié après commit.

  95. Systèmes event-sourcés · CQRS : séparer écriture et lecture

    Passer une projection en mémoire à un processus séparé avec un état dans PostgreSQL ne laisse pas le code des handlers inchangé : leur logique reste la même, mais l'écriture de l'état et la déduplication deviennent persistantes.

  96. Systèmes event-sourcés · DDD : les fondations qui comptent vraiment

    Dans la grammaire de Brandolini, les policies sont des post-its lilas et les aggregates de grands post-its jaunes ; le texte inversait aggregates et policies et donnait des policies blanches. Brandolini distingue trois formats, pas deux.

  97. Systèmes event-sourcés · DDD : les fondations qui comptent vraiment

    JSON.stringify d'une instance decimal.js donne une chaîne ("100.5") grâce à toJSON, pas {} ; ce sont Set et Map qui deviennent {}.

  98. Systèmes event-sourcés · DDD : les fondations qui comptent vraiment

    Les chapitres de Vernon sur bounded contexts, Value Objects, domain events et aggregates sont les chapitres 2, 6, 8 et 10 (le 7 traite des Services).

  99. Systèmes event-sourcés · DDD : les fondations qui comptent vraiment

    Le renommage des classes à la minification dépend des options du bundler (--keep-names chez esbuild, keep_classnames chez Terser) ; l'optimistic locking ne protège l'invariant que si l'append vérifie la version attendue.

  100. Systèmes event-sourcés · DDD : les fondations qui comptent vraiment

    Ajouter un champ à un événement publié ne casse que les consommateurs qui valident strictement le schéma ; le risque d'un champ currency ajouté est surtout que des consommateurs tolérants continuent de supposer des euros, sans erreur.

  101. Systèmes event-sourcés · De l'in-memory à la production

    SELECT MAX(...) FOR UPDATE est refusé par PostgreSQL, et un verrou sur la dernière ligne du stream ne fait pas voir à la seconde transaction la version insérée par la première en READ COMMITTED : c'est la contrainte UNIQUE qui garantit l'optimistic locking, pas un filet de secours. Le verrou utile est un advisory lock par stream ou une ligne de version mise à jour à chaque append.

  102. Systèmes event-sourcés · De l'in-memory à la production

    Le BIGSERIAL ordonne les événements dans l'ordre d'allocation de la séquence, pas dans l'ordre de commit ni d'insertion ; une projection qui lit au-delà de son checkpoint peut sauter un événement validé en retard.

  103. Systèmes event-sourcés · De l'in-memory à la production

    Un schéma par tenant n'isole que si chaque tenant a son propre rôle ; le search_path n'est pas une frontière de sécurité. La RLS est contournée par le propriétaire de la table (sauf FORCE ROW LEVEL SECURITY), les superutilisateurs et les rôles BYPASSRLS.

  104. Systèmes event-sourcés · De l'in-memory à la production

    La contrainte UNIQUE sur event_id ne déduplique un retry que si l'event_id est le même d'un essai à l'autre.

  105. Systèmes event-sourcés · De l'in-memory à la production

    Kafka : la compaction ne garde que la dernière valeur par clé et ne reconstitue pas un stream. DynamoDB : un PutItem conditionné par attribute_not_exists sur (stream, version) est l'équivalent direct de la contrainte UNIQUE.

  106. Systèmes event-sourcés · De l'in-memory à la production

    Le système ne fonctionne pas sans saga_state ni saga_processed_events : seules les tables de snapshots et de checkpoints se recalculent depuis events ; perdre l'état des sagas fait perdre leur déduplication.

  107. Systèmes event-sourcés · De l'in-memory à la production

    Le causationId n'est pas toujours l'eventId d'un événement : en tête de chaîne, il vaut l'identifiant de la requête ou de la commande. Le Kernel reçoit un seul EventStore ; combiner PostgreSQL et Kafka passe par une implémentation composite.

  108. Systèmes event-sourcés · De l'in-memory à la production

    Le catch de append() traduisait tout 23505 en conflit de version, y compris un doublon d'event_id, ce qui faisait relancer en boucle un retry déjà persisté : seule la contrainte (stream_name, event_version) signale un conflit. En SERIALIZABLE, ce conflit remonte souvent en 40001 et non en 23505.

  109. Systèmes event-sourcés · De l'in-memory à la production

    La matrice donnait à EventStoreDB un meilleur débit d'écriture qu'à PostgreSQL : son cluster a lui aussi un seul leader qui coordonne les écritures. L'ajout d'une colonne tenant_id rend les événements existants invisibles sous RLS jusqu'au remplissage, et le préfixe de stream impose de renommer les streams existants.

  110. Systèmes event-sourcés · De l'in-memory à la production

    La table projection_checkpoints était rangée parmi les caches qu'on peut perdre ; perdre la position en gardant un read model en table alimenté par incréments rejoue tout l'historique par-dessus et compte deux fois chaque événement. Elle se perd seulement avec les tables qu'elle décrit.

  111. Systèmes event-sourcés · Évolution des événements et correction des bugs

    Le fallback implicite sur v1 du registry faisait passer un événement de version courante ou inconnue dans l'upcaster v1 (montant NaN, sans erreur), et un seul upcaster était appliqué. Le registry applique désormais toute la chaîne jusqu'à la version courante et refuse une version inconnue.

  112. Systèmes event-sourcés · Évolution des événements et correction des bugs

    Un bug dans un handler de projection ou un apply d'aggregate se corrige par le code et un rebuild ; le Corrective Event sert quand le stream contient un fait faux, émis par le code qui décide. L'exemple et les trois situations ont été réécrits en ce sens, et l'aggregate doit aussi appliquer la correction.

  113. Systèmes event-sourcés · Évolution des événements et correction des bugs

    La taxonomie en cinq classes n'est pas celle de Greg Young ; l'attribution est retirée. Un changement de sens ou un renommage passe par une nouvelle version et un upcaster, pas nécessairement par un nouveau type.

  114. Systèmes event-sourcés · Évolution des événements et correction des bugs

    L'obligation réglementaire était énoncée de façon trop large (MiFID II, DORA, HIPAA) : le texte vérifié est l'article 72 du règlement délégué 2017/565 pour MiFID II, qui exige justement que les corrections et l'état antérieur restent retrouvables. L'append-only s'impose par REVOKE ou trigger, et ne prouve pas à lui seul l'absence d'altération.

  115. Systèmes event-sourcés · Évolution des événements et correction des bugs

    Publier v1 et v2 d'un integration event sur le même topic les livre à tous les consommateurs, qui doivent filtrer ; le test « ne lève pas d'exception » laissait passer un montant null converti en 0.

  116. Systèmes event-sourcés · Évolution des événements et correction des bugs

    Le rollback d'un upcasting n'est trivial que tant qu'aucun événement n'a été écrit dans la nouvelle version ; ensuite, l'ancien code les refuse. Le coût d'exécution de l'upcasting était présenté comme le motif du copy-and-transform, alors que le chapitre le dit faible : c'est la maintenance qui pèse.

  117. Systèmes event-sourcés · Évolution des événements et correction des bugs

    Le copy-and-transform ne commence plus par une double écriture dans les deux streams, qui faisait figurer les événements récents deux fois et avant l'historique dans le nouveau stream, et compter deux fois par une projection qui lit les deux (voir le chapitre 18). Une correction en masse passe d'abord par des Corrective Events émis par lots, le copy-and-transform restant réservé aux changements de forme.

  118. Systèmes event-sourcés · Évolution des événements et correction des bugs

    REVOKE et trigger ne protègent pas l'event store si l'application se connecte avec le rôle propriétaire de la table, qui peut se rendre ses droits et désactiver un trigger : le rôle des migrations et celui de l'application doivent être distincts.

  119. Systèmes event-sourcés · Évolution des événements et correction des bugs

    Un copy-and-transform dans la même table fait relire l'historique copié comme de nouveaux événements par les projections qui suivent le journal global, et la contrainte UNIQUE sur event_id oblige à attribuer de nouveaux identifiants aux copies. Avro (alias) et Protobuf (numéros de champ) gèrent aussi le renommage d'un champ.

  120. Systèmes event-sourcés · GDPR et le log immuable

    Un identifiant opaque relié à un nom dans un autre système était présenté comme non personnel ; c'est une donnée pseudonymisée, donc personnelle (considérant 26), comme un solde rattaché au compte. La classification oppose désormais données identifiantes et données de domaine.

  121. Systèmes event-sourcés · GDPR et le log immuable

    L'ICO et l'EDPB étaient dits avoir reconnu le crypto-shredding comme effacement ; aucun des deux ne le valide en tant que tel. Le texte expose ce que disent réellement le considérant 26, l'ICO (mise « beyond use » des sauvegardes) et le rapport EDPB 2025.

  122. Systèmes event-sourcés · GDPR et le log immuable

    La citation de l'article 17(3) était inexacte ; l'obligation légale de conservation relève du point b, limitée aux données que cette obligation exige. Une pièce justificative comptable peut elle-même contenir des données identifiantes.

  123. Systèmes event-sourcés · GDPR et le log immuable

    Snapshots et projections étaient dits contenir des copies chiffrées avec la même clé ; ils stockent le plus souvent la valeur en clair, que la destruction de la clé n'atteint pas.

  124. Systèmes event-sourcés · GDPR et le log immuable

    AWS KMS : le délai de ScheduleKeyDeletion va de 7 à 30 jours (30 par défaut). Ajout du coût d'une clé KMS par utilisateur et du chiffrement d'enveloppe, avec le piège des clés enveloppées présentes dans les backups.

  125. Systèmes event-sourcés · GDPR et le log immuable

    Une projection reconstruite sans tombstone était dite retrouver l'état d'avant l'effacement ; elle ne retrouve pas la donnée, mais ignore qu'il y a eu effacement.

  126. Systèmes event-sourcés · GDPR et le log immuable

    Avec le chiffrement d'enveloppe, la clé effacée n'est pas une clé KMS : CloudTrail et ScheduleKeyDeletion ne prouvent la destruction que dans le modèle à une clé KMS par utilisateur ; sinon la preuve est la suppression journalisée de la clé de données enveloppée. Le texte citait aussi un appel DeleteKey qui n'existe pas dans l'API AWS KMS.

  127. Systèmes event-sourcés · GDPR et le log immuable

    L'obligation d'informer les destinataires (article 19) connaît une exception quand l'information est impossible ou exige des efforts disproportionnés. La suppression ou la réécriture d'un stream, présentée comme exclue, est une option possible avec ses coûts (chapitre 11).

  128. Systèmes event-sourcés · GDPR et le log immuable

    Le pseudo-code de chiffrement retombait sur l'identifiant du stream quand l'événement ne portait pas d'userId : ces champs échappaient à l'effacement de la clé de l'utilisateur. Il refuse désormais ce cas, et le texte signale la création concurrente de clés et la recréation d'une clé après effacement.

  129. Systèmes event-sourcés · GDPR et le log immuable

    La citation de l'article 5, paragraphe 1, point e) est rétablie (« sous une forme permettant l'identification ») ; ajout du délai d'un mois de l'article 12, paragraphe 3, ainsi que du coût et de l'atomicité du Personal Data Store.

  130. Systèmes event-sourcés · GDPR et le log immuable

    La checklist exigeait que toutes les clés résident hors de la base, ce qui contredisait le chiffrement d'enveloppe décrit plus haut : seules les clés de données enveloppées peuvent être en base, la clé maîtresse reste dans le KMS.

  131. Systèmes event-sourcés · Glossaire

    Append-only : l'EventStore l'est par son interface ; en base, il faut retirer UPDATE et DELETE ou poser un trigger, et l'effacement RGPD peut imposer une exception.

  132. Systèmes event-sourcés · Glossaire

    globalPosition suit l'ordre d'allocation de la séquence, pas l'ordre de commit : il ordonne de façon déterministe un rebuild sur des événements validés, mais une lecture en direct doit gérer les transactions validées en retard et les trous.

  133. Systèmes event-sourcés · Glossaire

    Les versions d'un stream commencent à 0 dans l'implémentation de référence : la version d'un stream est celle de son dernier événement, soit le nombre d'événements moins un.

  134. Systèmes event-sourcés · Glossaire

    L'Outbox ne perd pas d'événement mais livre au moins une fois : un crash après publication et avant marquage produit un doublon, d'où des consommateurs idempotents.

  135. Systèmes event-sourcés · Glossaire

    La déduplication par eventId ne rend une projection idempotente que si la trace de l'eventId est écrite dans la même transaction que le read model.

  136. Systèmes event-sourcés · Glossaire

    Des données chiffrées dont la clé existe encore sont des données pseudonymisées, donc personnelles ; le crypto-shredding ne vaut effacement que si aucune copie de la clé ne survit.

  137. Systèmes event-sourcés · Glossaire

    Les sagas du dossier (SagaBase, SagaManager) sont stateful : ce sont techniquement des Process Managers qui gardent le nom de saga, et non des sagas sans état opposées aux Process Managers, comme l'entrée le laissait entendre.

  138. Systèmes event-sourcés · Lectures commentées

    Le talk de Sara Pellegrini s'intitule « Kill Aggregate! » et date de 2023 ; l'attribution à Devoxx 2022-2023 n'a pas pu être vérifiée.

  139. Systèmes event-sourcés · Lectures commentées

    « Clarified CQRS » d'Udi Dahan traite des raisons de CQRS, des commandes, des requêtes et de la synchronisation du modèle de lecture, pas de la distinction entre domain events et integration events.

  140. Systèmes event-sourcés · Lectures commentées

    L'article CQRS de Fowler ne dit pas que CQRS n'exige pas l'Event Sourcing ; il le présente comme un complément fréquent et met en garde contre CQRS hors d'un bounded context qui le justifie.

  141. Systèmes event-sourcés · Lectures commentées

    Le talk de Maxim Fateev à QCon London est « Escape Queue Abyss With Durable Execution » (2023), donné seul ; le titre et le co-auteur cités n'existaient pas.

  142. Systèmes event-sourcés · Lectures commentées

    L'entrée « Eventide Project, Deleting Data in Event-Sourced Systems (eventstore.com) » mêlait deux projets distincts et n'a pas pu être retrouvée ; elle est remplacée par l'avis du G29 sur l'anonymisation et les lignes directrices de l'EDPB sur la pseudonymisation.

  143. Systèmes event-sourcés · Lectures commentées

    Le talk de Michiel Rook s'intitule « Forget me, please? Event sourcing and the GDPR » (JAX London 2018).

  144. Systèmes event-sourcés · Lectures commentées

    Le code de l'ICO sur l'anonymisation (2012) relève du droit britannique et a été mis en révision ; il est remplacé par les textes européens, qui tiennent une donnée chiffrée dont la clé existe pour pseudonymisée, donc personnelle.

  145. Systèmes event-sourcés · Les Aggregates en profondeur

    Sans contrôle de version, deux retraits concurrents s'ajoutent tous deux au stream et le compte finit à -400 € ; le « 200 € ou 400 € » est le lost update d'un modèle à état mutable.

  146. Systèmes event-sourcés · Les Aggregates en profondeur

    Le replay ne publie rien par construction, mais il n'est déterministe et sans effet de bord que si les handlers @When ne lisent que l'état et l'événement ; le retry après conflit refait aussi les effets externes produits avant l'append.

  147. Systèmes event-sourcés · Les Aggregates en profondeur

    Code corrigé : l'append en mémoire plantait sur un stream neuf (non-null assertion sur un Map.get absent), et le CommandBus affectait une variable lastError non déclarée ; la vérification en mémoire n'est atomique que sans await entre contrôle et écriture.

  148. Systèmes event-sourcés · Les Aggregates en profondeur

    Supprimer les snapshots avant de déployer laisse l'ancien code en reprendre ; l'invalidation sûre passe par une version de snapshot ignorée au chargement.

  149. Systèmes event-sourcés · Les Aggregates en profondeur

    La transaction time n'est pas strictement monotone (horloge murale, plusieurs serveurs) et globalPosition suit l'ordre d'allocation, pas l'ordre de commit ; les termes valid time et transaction time datent de Snodgrass et Ahn, 1985.

  150. Systèmes event-sourcés · Les Aggregates en profondeur

    Le scénario d'ouverture attribuait à un handler @When impur une OptimisticConcurrencyError après trois retries ; un @When impur fausse l'état rechargé, il ne provoque pas de conflit de version. Et la sûreté du retry ne tient pas à l'Event Sourcing : elle vient du rechargement de l'état et de la décision refaite, ce qu'un modèle à état mutable versionné fait aussi.

  151. Systèmes event-sourcés · Patterns de résilience

    L'exemple d'inbox appliquait la mise à jour avant l'INSERT … ON CONFLICT DO NOTHING : un doublon était détecté mais le second crédit était quand même validé. L'INSERT passe en premier et conditionne la mise à jour, en une seule instruction.

  152. Systèmes event-sourcés · Patterns de résilience

    Plusieurs pollers en SKIP LOCKED publient des lots en parallèle et peuvent inverser deux événements d'un même stream ; une entrée envoyée en DLQ rompt aussi l'ordre de son stream. Les deux conséquences et leurs parades sont ajoutées.

  153. Systèmes event-sourcés · Patterns de résilience

    Le gestionnaire Idempotency-Key lisait puis écrivait la clé : deux retries simultanés, ou un arrêt avant l'enregistrement, exécutaient deux virements. Réservation atomique, empreinte du corps (422), requête en cours (409) et identifiant dérivé de la clé.

  154. Systèmes event-sourcés · Patterns de résilience

    Le brouillon IETF Idempotency-Key ne recommande aucune durée et n'est pas une RFC ; Stripe garde ses clés 24 heures sur l'API v1 et 30 jours sur l'API v2.

  155. Systèmes event-sourcés · Patterns de résilience

    Le coût d'un poll indexé suit le nombre d'entrées en attente, pas O(100) ; l'index partiel porte désormais sur id, l'ordre du poll. Un rejet non attendu d'un listener asynchrone arrête par défaut le processus Node.js au lieu d'être ignoré.

  156. Systèmes event-sourcés · Patterns de résilience

    Un retry avec backoff rompt lui aussi l'ordre d'un stream, avant toute DLQ, puisque le poll publie les entrées suivantes pendant que l'entrée fautive attend : parade ajoutée. La clé d'idempotence et le transferId qui en dérive sont désormais rangés par client, et le refus du doublon suppose une création de stream qui exige un stream neuf.

  157. Systèmes event-sourcés · Patterns de résilience

    L'AsyncEventBus était jugé acceptable en production avec des sagas dans le même processus ; une saga qui manque un événement ne se reconstruit pas (c'est le scénario d'ouverture) : il faut un rattrapage au démarrage ou l'outbox. Le retry Idempotency-Key après un arrêt recevait une erreur alors que le virement existait : le refus du stream existant se traite comme un succès. La comparaison avec le CDC ajoute l'ordre de commit, la clé de partition Kafka et la synchronisation des slots depuis PostgreSQL 17.

  158. Systèmes event-sourcés · Patterns de résilience

    Outbox et Inbox n'appliquent un effet une seule fois que pour les effets écrits en base dans la même transaction que la marque de l'Inbox ; un appel externe demande en plus une clé d'idempotence côté destinataire.

  159. Systèmes event-sourcés · Pourquoi Event Sourcing (et quand ne pas l'utiliser)

    Les tables temporelles (SQL Server, MariaDB) donnent l'état à une date par une requête FOR SYSTEM_TIME AS OF ; ce qui leur manque est la cause du changement, pas l'état passé.

  160. Systèmes event-sourcés · Pourquoi Event Sourcing (et quand ne pas l'utiliser)

    En cas de conflit de version, le stream ne conserve que l'écriture acceptée, pas les deux tentatives ; une colonne version dans un modèle CRUD détecte le même conflit.

  161. Systèmes event-sourcés · Pourquoi Event Sourcing (et quand ne pas l'utiliser)

    Rejouer un stream corrige une erreur d'interprétation dans un handler @When, pas un événement faux émis par une décision boguée, qui demande un événement de compensation.

  162. Systèmes event-sourcés · Pourquoi Event Sourcing (et quand ne pas l'utiliser)

    L'immuabilité des événements tient à l'interface de l'EventStore ; en base, elle demande des droits retirés ou un trigger, et la valeur probante du journal dépend de ces protections.

  163. Systèmes event-sourcés · Pourquoi Event Sourcing (et quand ne pas l'utiliser)

    Rejouer une commande sur l'état reconstitué reproduit un bug lié à l'état, pas une race condition qui dépend de l'entrelacement de deux commandes.

  164. Systèmes event-sourcés · Pourquoi Event Sourcing (et quand ne pas l'utiliser)

    globalPosition suit l'ordre d'allocation de la séquence, pas l'ordre de commit : deux transactions concurrentes peuvent valider dans l'ordre inverse, et une annulation laisse un trou.

  165. Systèmes event-sourcés · Pourquoi Event Sourcing (et quand ne pas l'utiliser)

    applyFromHistory() ne produit pas de nouvel événement mais n'empêche pas un handler @When d'avoir un effet de bord ; le replay est sûr tant que ces handlers restent purs.

  166. Systèmes event-sourcés · Pourquoi Event Sourcing (et quand ne pas l'utiliser)

    L'eventual consistency n'est pas inévitable : une projection mise à jour dans la même transaction que l'écriture des événements est à jour dès la commande validée.

  167. Systèmes event-sourcés · Pourquoi Event Sourcing (et quand ne pas l'utiliser)

    Un événement validé avant l'insertion d'un autre a une globalPosition inférieure seulement si la séquence garde son cache par défaut de 1 ; avec un CACHE supérieur, chaque session réserve un bloc et l'ordre entre sessions n'est plus garanti.

  168. Systèmes event-sourcés · Projections et Read Models

    Une livraison exactly-once n'est pas atteignable en général, mais un effet exactly-once l'est, par l'idempotence ou en validant le read model et sa position dans la même transaction.

  169. Systèmes event-sourcés · Projections et Read Models

    BaseProjection marquait l'événement comme traité avant d'appeler le handler : un handler en échec perdait l'événement au retry. Le marquage se fait désormais après.

  170. Systèmes event-sourcés · Projections et Read Models

    Sans super.reset(), un rebuild dans le même processus ignore tous les événements rejoués et laisse le read model vide ; les événements live suivants ne sont pas bloqués par la déduplication, contrairement à ce qui était écrit.

  171. Systèmes event-sourcés · Projections et Read Models

    globalPosition suit l'ordre d'allocation de la séquence, pas l'ordre de commit ; une projection qui lit au-delà de son checkpoint peut sauter un événement validé en retard. L'unicité vient de la clé primaire, pas de la séquence.

  172. Systèmes event-sourcés · Projections et Read Models

    Un warm restart qui restaure l'état et la position sauvegardés ensemble n'applique pas deux fois un événement ; l'idempotence sert quand le read model est écrit en continu et que le checkpoint le suit avec retard.

  173. Systèmes event-sourcés · Projections et Read Models

    La déduplication SQL et l'incrément doivent être validés dans la même transaction ; l'exemple est désormais une seule instruction.

  174. Systèmes event-sourcés · Projections et Read Models

    Invalider le checkpoint d'une projection persistée en table ne suffit pas : il faut aussi vider la table du read model et sa table de déduplication.

  175. Systèmes event-sourcés · Projections et Read Models

    Une projection écrit à chaque événement en mode live : ses index ont un coût à chaque écriture, contrairement à ce qui était écrit.

  176. Systèmes event-sourcés · Projections et Read Models

    Le claim d'un segment Axon peut être repris après expiration : deux instances peuvent alors traiter les mêmes événements, d'où des handlers idempotents.

  177. Systèmes event-sourcés · Projections et Read Models

    Le scénario d'interblocage décrit n'était pas cohérent ; le blocage réel vient d'une gap detection sur les positions globales chez un worker qui ne reçoit qu'une catégorie.

  178. Systèmes event-sourcés · Projections et Read Models

    Écrire le checkpoint à chaque événement n'est trop coûteux que pour une projection en mémoire qui sérialise son état avec la position ; pour un read model en table, valider la position dans la même transaction que la table est la méthode recommandée, ce que le chapitre disait ailleurs.

  179. Systèmes event-sourcés · Projections et Read Models

    L'UPSERT de AccountOpened (DO UPDATE SET owner) remettait l'ancien titulaire si un doublon arrivait après un changement ; l'exemple utilise DO NOTHING.

  180. Systèmes event-sourcés · Projections et Read Models

    La déduplication SQL marquait comme traité un dépôt visant un compte encore absent du read model, et le perdait sans erreur ; le chapitre indique comment le détecter et annuler.

  181. Systèmes event-sourcés · Projections et Read Models

    Pendant un rebuild, la clé primaire du read model doit rester en place : ON CONFLICT l'exige et les UPDATE par clé en dépendent. Seuls les index secondaires se créent après le chargement.

  182. Systèmes event-sourcés · Projections et Read Models

    Invalider le checkpoint et vider la table ne déclenche un rebuild que si tous les projecteurs, ancienne version comprise, sont arrêtés ; sinon ils réécrivent leur position.

  183. Systèmes event-sourcés · Projections et Read Models

    globalPosition suit l'ordre causal des transactions seulement si la séquence garde son CACHE par défaut de 1. Une troisième parade aux commits hors ordre est ajoutée : lire sous le xmin du snapshot avec un checkpoint (transaction_id, position).

  184. Systèmes event-sourcés · Projections et Read Models

    Un handler en mémoire qui modifie l'état puis échoue est rejoué en entier au retry : il doit calculer avant d'écrire. Un rejeu à une date reflète l'interprétation du code actuel, sur une instance dédiée.

  185. Systèmes event-sourcés · Projections et Read Models

    Après correction d'un handler incrémental, un warm restart ne répare pas les soldes mis à jour depuis le checkpoint : seuls les comptes ouverts après lui sont justes.

  186. Systèmes event-sourcés · Projections et Read Models

    Sérialiser les écritures par un advisory lock ne rend l'ordre d'allocation égal à l'ordre de commit que si la séquence garde un CACHE de 1 ; avec un cache plus grand, une session peut insérer sous le verrou une valeur réservée plus tôt et plus basse.

  187. Systèmes event-sourcés · Sagas et Process Managers

    Persister l'état et marquer l'événement avant de dispatcher ne suffit pas : un arrêt entre la marque et le dispatch perd les commandes. L'état, la marque et les commandes (outbox) s'écrivent dans une même transaction, et la clé primaire de déduplication tranche entre deux livraisons concurrentes.

  188. Systèmes event-sourcés · Sagas et Process Managers

    Le contrôle de déduplication du compte destination n'empêche pas un crédit arrivé après la compensation (saga zombie) ; ajout des deux parades : timeout qui ne compense pas un résultat inconnu, instance créée seulement sur l'événement de démarrage.

  189. Systèmes event-sourcés · Sagas et Process Managers

    La saga de Garcia-Molina et Salem n'est pas sans état : le système journalise sa progression pour savoir quoi compenser après une panne. Le papier fait 11 pages, pas 12.

  190. Systèmes event-sourcés · Sagas et Process Managers

    AWS Step Functions et Conductor décrivent le workflow comme une machine à états en JSON, pas comme du code ; Temporal rejoue le code du workflow contre l'historique, et relance par défaut une activité en échec sans limite. L'exemple utilise désormais l'API réelle du SDK TypeScript.

  191. Systèmes event-sourcés · Sagas et Process Managers

    Le bug du dispatch avant persistance se reproduit à chaque exécution en mode synchrone, donc en test ; un Set ou une Map restaurés depuis JSON lèvent un TypeError au lieu de renvoyer undefined ; 100 événements par seconde font 8,64 millions de lectures par jour, pas un million.

  192. Systèmes event-sourcés · Sagas et Process Managers

    Dispatcher avant de persister ne restaure pas l'état antérieur dans le premier traitement : les traitements imbriqués lisent l'état d'avant, puis la sauvegarde du premier écrase la leur. Dans la saga zombie, l'instance vierge dispatche CompleteTransfer pour un virement en échec. La compensation du workflow Temporal, déclenchée après un crédit expiré, expose au même scénario que la saga zombie.

  193. Systèmes event-sourcés · Sagas et Process Managers

    Dans l'exemple Temporal, la compensation partageait le plafond de cinq essais du crédit et pouvait abandonner en laissant le débit en place ; elle garde désormais la relance sans limite. Un timeout ne renseigne jamais sur l'issue de l'étape en cours, et le handler qui le traite a besoin d'un statut explicite pour savoir quoi compenser.

  194. Systèmes event-sourcés · Scaling et opérations

    CREATE OR REPLACE VIEW échoue quand la nouvelle table ajoute une colonne ailleurs qu'à la fin ou en retire une : le cutover et le rollback se font par DROP VIEW et CREATE VIEW dans une même transaction. Le contre-exemple « hors transaction » visait à tort une instruction unique, déjà atomique.

  195. Systèmes event-sourcés · Scaling et opérations

    Les instructions préparées ne restent pas sur l'ancienne table après la bascule : PostgreSQL les ré-analyse, et un SELECT * préparé échoue avec « cached plan must not change result type ».

  196. Systèmes event-sourcés · Scaling et opérations

    La clé de partition hash(aggregateId + globalPosition / 1000) casse l'ordre des événements d'un même aggregate ; elle ne convient qu'à des handlers indépendants de l'ordre.

  197. Systèmes event-sourcés · Scaling et opérations

    Dans Axon, un segment n'est pas une plage de tokens : la SequencingPolicy décide à quel segment appartient un événement. Le consistent hashing date de Karger et al. (1997), le papier Dynamo a popularisé les virtual nodes, et déplacer un aggregate chaud ne le parallélise pas.

  198. Systèmes event-sourcés · Scaling et opérations

    L'index partiel WHERE last_processed_pos < (SELECT MAX(id) FROM events) est refusé par PostgreSQL : un prédicat d'index ne peut pas contenir de sous-requête.

  199. Systèmes event-sourcés · Scaling et opérations

    Un lag nul exige une projection synchrone dans la transaction d'append, ce qui reste de l'event sourcing ; la fraîcheur vue par l'utilisateur se mesure par l'âge du plus ancien événement non traité, en plus du lag en événements.

  200. Systèmes event-sourcés · Scaling et opérations

    Le Lazy Backfill ne détecte pas un changement de logique par la seule position : chaque ligne doit porter la version de projection qui l'a écrite, et une ligne d'une version antérieure se rejoue sur tout son stream.

  201. Systèmes event-sourcés · Scaling et opérations

    Un checkpoint de position ne remplace la déduplication que s'il est validé dans la même transaction que le read model, et tenu par partition quand le rebuild est partitionné.

  202. Systèmes event-sourcés · Scaling et opérations

    Une vue recréée par DROP et CREATE perd ses droits : sans GRANT dans la même transaction, l'application reçoit « permission denied » au cutover. À la migration, V1 continue depuis son checkpoint ; seule V2 se reconstruit depuis le début.

  203. Systèmes event-sourcés · Scaling et opérations

    Le Lazy Backfill ne rend correctes que les lectures par clé ; listes et filtres lisent des lignes non rejouées. La projection live doit rejouer, et non incrémenter, une ligne d'ancienne version, et le backfill sélectionne les lignes par version, pas par position.

  204. Systèmes event-sourcés · Scaling et opérations

    Partitionner un rebuild parallélise le traitement, pas la lecture du journal, que chaque worker relit sans colonne de partition indexée ; la barrière ne donne une projection cohérente que si tous les workers s'arrêtent à la même position cible.

  205. Systèmes event-sourcés · Tester un système event-sourcé

    PostgreSQL n'ajoute pas une « isolation FOR UPDATE SKIP LOCKED sans deadlock » ni une durabilité qui survit à une panne disque : la contrainte d'unicité (stream, version) départage deux appends concurrents en READ COMMITTED, les verrous peuvent s'interbloquer, et la perte de disque relève de la réplication et des sauvegardes.

  206. Systèmes event-sourcés · Tester un système event-sourcé

    Le test de concurrence doit faire écrire deux instances du même aggregate, pas deux aggregates distincts, pour provoquer une OptimisticConcurrencyError.

  207. Systèmes event-sourcés · Tester un système event-sourcé

    L'exemple Ajv ne compilait pas en mode strict sans ajv-formats, et validait une instance sans occurredOn avec un identifiant non UUID : il échouait toujours. L'exemple Pact utilisait une interaction HTTP pour un événement ; il utilise désormais un pact de message.

  208. Systèmes event-sourcés · Tester un système event-sourcé

    La propriété fast-check n'était jamais exécutée (fc.property sans fc.assert) ; « idempotence du replay » désignait en fait le déterminisme ; fast-check génère cent cas par défaut, pas des centaines. Un vi.fn() enregistre bien les arguments : ce qu'il ne vérifie pas, c'est le routage vers un handler.

  209. Systèmes event-sourcés · Tester un système event-sourcé

    Les tests sont déterministes à condition que les handlers soient purs ; le module PostgreSQL de Testcontainers demande l'image en argument.

  210. Systèmes event-sourcés · Tester un système event-sourcé

    Un invariant se vérifie sur des séquences aléatoires de commandes, pas d'événements (le replay n'applique aucune règle), et le property-based testing cherche un contre-exemple sans prouver l'invariant. Le test de déduplication d'une saga en mémoire ne couvre pas deux livraisons simultanées, que seule la clé primaire en base départage. Supprimer l'état d'une saga terminée évite une table qui grossit et le rechargement d'un ancien état par un événement tardif.

  211. Systèmes event-sourcés · Tester un système event-sourcé

    Un rebuild ne reproduit la projection incrémentale que si celle-ci a reçu les événements dans l'ordre de globalPosition, ce qui n'est pas acquis entre streams en production. La durabilité au commit suppose fsync et synchronous_commit à on. Les tests unitaires de saga utilisent un vrai CommandBus aux handlers mockés, pas un CommandBus mocké ; la contrainte s'appelle (stream_name, event_version) comme aux chapitres 4 et 9, et son 23505 doit être traduit en OptimisticConcurrencyError.

Corrections · Deepstack