Je me rends compte que la question ci-dessus soulève probablement quelques «quoi», mais laissez-moi essayer d'expliquer:
J'essaie d'envelopper ma tête sur quelques concepts connexes, essentiellement le modèle Saga ( http://www.rgoarchitects.com/Files/SOAPatterns/Saga.pdf ) en combinaison avec Event-sourcing (Un concept DDD : http://en.wikipedia.org/wiki/Domain-driven_design )
Un bon article qui le regroupe: https://blog.jonathanoliver.com/cqrs-sagas-with-event-sourcing-part-ii-of-ii/
J'arrive à la question dans une minute, mais je pense que je dois essayer de résumer ce que je comprends d'abord (ce qui pourrait bien être faux, alors veuillez corriger si c'est le cas) car cela pourrait bien avoir un impact sur la raison pour laquelle je suis poser la question pour commencer:
- Le modèle Saga est une sorte de courtier qui, étant donné une action (utilisateur final, automatisé, etc. essentiellement tout ce qui va changer les données), divise cette action en activités commerciales et envoie chacune de ces activités sous forme de messages à un bus de messages qui à son tour l'envoie aux racines agrégées respectives à prendre en charge.
- Ces racines agrégées peuvent fonctionner de manière totalement autonome (belle séparation des préoccupations, grande évolutivité, etc.)
- Une instance Saga elle-même ne contient aucune logique métier, qui est contenue dans les racines agrégées auxquelles elle envoie des activités. La seule «logique» contenue dans la saga est la logique de «processus», (souvent implémentée comme une machine à états), qui détermine en fonction des actions reçues (ainsi que des événements de suivi) ce qu'il faut faire (c'est-à-dire: quelles activités envoyer)
- Les modèles Saga implémentent une sorte de modèle de transaction distribuée. C'est-à-dire: lorsque l'une des racines agrégées (qui fonctionnent à nouveau de manière autonome, sans se connaître mutuellement) échoue, l'action entière peut devoir être annulée.
- Ceci est mis en œuvre en ayant toutes les racines agrégées, à la fin de leur rapport d'activité à la Saga. (En cas de succès ainsi que d'erreur)
- Dans le cas où toutes les racines agrégées retournent un succès, la statemachine interne si la Saga détermine quoi faire ensuite (ou décide que c'est fait)
- En cas d'échec, la Saga envoie à toutes les racines agrégées qui ont participé à la dernière action une action dite de compensation, c'est-à-dire: une action pour annuler la dernière action effectuée par chacune des racines agrégées.
- Cela pourrait simplement faire un «vote moins 1» si l'action était «plus 1 vote», mais cela pourrait être plus compliqué comme restaurer un blog à sa version précédente.
- L'événementiel (voir le blog combinant les deux) vise à externaliser la sauvegarde des résultats de chacune des activités que chacune des racines agrégées entreprend dans un magasin d'événements centralisé (les changements sont appelés «événements» dans ce contexte)
- Ce magasin d'événements est la «version unique de la vérité» et peut être utilisé pour rejouer l'état de toutes les entités simplement en itérant les événements stockés (essentiellement comme un journal des événements)
- La combinaison des deux (c.-à-d. Laisser les racines agrégées utiliser Event-sourcing pour externaliser la sauvegarde de leurs modifications avant de rendre compte à la Saga) offre de nombreuses possibilités intéressantes, dont l'une concerne ma question ...
Je sentais que je devais retirer cela de mon épaule, car c'est beaucoup à saisir en une seule fois. Compte tenu de ce contexte / état d'esprit (encore une fois, veuillez corriger si vous avez tort)
la question: lorsqu'une racine agrégée reçoit une action de compensation et si cette racine agrégée a externalisé ses changements d'état à l'aide de la source d'événements, l'action de compensation dans toutes les situations ne serait-elle pas simplement une suppression du dernier événement du magasin d'événements pour cela compte tenu de la racine globale? (En supposant que la mise en œuvre persistante autorise les suppressions)
Cela aurait beaucoup de sens pour moi (et serait un autre grand avantage de cette combinaison), mais comme je l'ai dit, je pourrais faire ces hypothèses sur la base d'une compréhension incorrecte / incomplète de ces concepts.
J'espère que cela n'a pas été trop long.
Merci.
la source
Pour être complet, j'ai pensé à inclure un extrait pertinent de Martin Fowler sur les moyens de revenir à l'état:
De: http://martinfowler.com/eaaDev/EventSourcing.html
la source
Conceptuellement:
Nous ne pouvons changer notre futur état qu'en exécutant une autre commande (Compenser Action) qui devrait entraîner un changement d'état des événements de l'application.
Pour "désembrouiller" la question, pensez à cette phrase "supprimer du dernier événement":
En bref, vous n'avez pas la possibilité de supprimer des événements dans le modèle CQRS.
Vous pouvez réduire votre magasin d'événements en créant un état d'instantané (qui est basé sur tous les événements menant à cet état), mais cet aspect physique n'a rien à voir avec le concept d'événement.
la source
Geert-Jan, je pense moi aussi que l'action de compensation peut simplement supprimer le ou les événements correspondants. Cela a du sens et montre un autre avantage du modèle de conception Event Sourcing: une mise en œuvre plus facile du modèle de conception de transaction de compensation.
Certains disent que la suppression de l'événement viole les «principes» de la recherche d'événements ou CQRS. Je pense que c'est une généralisation limitante. Je pense qu'il est correct de supprimer un événement s'il a été créé dans le cadre d'une transaction globale qui est annulée. Considérez le pseudocode:
Supposons que votre magasin d'événements soit une base de données transactionnelle. Dans le pseudocode, vous pouvez imaginer la situation où vous avez inséré le premier événement, mais lorsque vous essayez d'insérer le deuxième événement, une exception a été levée. La commande de restauration annulerait naturellement l'insertion du premier événement. Est-ce raisonnable?
S'il est raisonnable pour une transaction de base de données ACID (transaction avec commit / rollback), pourquoi ne serait-il pas raisonnable pour une transaction compensatrice?
Lors de l'exécution de la transaction Saga globale, les modifications des données peuvent être annulées (par compensation). Il n'est pas nécessaire de conserver l'événement créé lors de la transaction car la transaction ne s'est pas terminée.
Maintenant, si la compensation tente de supprimer un événement et que cet événement n'est pas le plus récent événement sur un objet, la suppression ne doit pas se produire. Mais en général, cela ne se produira probablement pas, en particulier dans les solutions à lecture intensive.
la source
Jouons avec l'idée que le stockage d'événements n'est que des données que vous souhaitez enregistrer. Par exemple, nous pouvons avoir un disque dur, nous pouvons commencer au début et y écrire des données. Chaque fois que nous avons un événement, nous ajoutons nos données précédentes, nous continuons donc d'écrire sur le disque où nous nous sommes arrêtés la dernière fois. Lorsque nous voulons supprimer un événement, nous revenons en arrière, supprimons cette partie du disque et laissons un espace. Revenir en arrière ralentit notre stockage d'événements, mais nous pouvons vivre avec cela. Si nous utilisons un système de fichiers, cela tentera de combler le vide avec ces derniers événements, donc nous finirons par avoir un stockage fragmenté lent ou nous pouvons faire une défragmentation. Nous n'aimons ni l'un ni l'autre. Si nous parlons de bases de données, vous obtenez ceci si vous utilisez une base de données relationnelle au lieu d'une base de données à ajouter uniquement pour stocker vos événements:
réf: https://cambridge-intelligence.com/bringing-time-series-data-to-life-with-keylines/
Ofc. par un site normal, cela n'a pas d'importance, mais ces solutions sont conçues pour d'énormes sites Web tels que facebook, google, etc. vous appelez la compensation quelque chose comme construire une machine à remonter le temps et remonter dans le temps pour changer ou empêcher un événement ???
Autant que je sache. la seule façon de résoudre ce problème consiste à créer un nouveau stockage d'événements dans lequel vous excluez les événements que vous ne souhaitez pas avoir, puis à supprimer l'ancien stockage d'événements. Mais c'est une solution extrême pour supprimer un seul événement. Si nous parlons du RGPD, la seule bonne solution relative que je connaisse est de stocker des données personnelles chiffrées dans le stockage des événements et de supprimer la clé de chiffrement d'une base de données différente.
la source