上記の質問はおそらくいくつかの「何ですか??」を引き起こすことに気づきましたが、説明させてください:
私はいくつかの関連する概念、つまり基本的にはSagaパターン( http://www.rgoarchitects.com/Files/SOAPatterns/Saga.pdf )とEventの組み合わせに頭を抱えようとしています-ソーシング(A DDDの概念: http://en.wikipedia.org/wiki/Domain-driven_design )
それをまとめた良い記事: https://blog.jonathanoliver.com/cqrs-sagas-with-event-sourcing-part-ii-of-ii/
私はすぐに質問にたどり着きましたが、私が最初に理解したことを要約する必要があると思います(これは間違っている可能性があるので、その場合は修正してください)。まず質問する:
一度に把握するのは大変なので、肩から外す必要があると感じました。このコンテキスト/マインドセットが与えられた場合(もう一度、間違っている場合は修正してください)
質問:集約ルートが補償アクションを受け取ったとき、その集約ルートがアウトソーシングしている場合、イベントソーシングを使用して状態変更を行うと、補償は行われません。すべての状況でのアクションは、その特定の集約ルートのイベントストア内の最後のイベントの削除だけですか? (persist-implementationが削除を許可すると仮定)
それは私には非常に理にかなっています(そしてこの組み合わせのもう1つの大きな利点になります)が、私が言ったように、私はこれらの概念の誤った/不完全な理解に基づいてこれらの仮定をしているかもしれません。
これが長続きしないことを願っています。
ありがとう。
イベントストアからイベントを削除しないでください。これらは起こったことを表しています。何かが今発生した場合は、それも知っておく必要があります。したがって、アグリゲートを強制的に以前の状態に戻すイベントを追加します。データベースから情報を削除するのは残念です。
greg youngのカートの例と削除されたアイテムについて考えてみましょう。明日になるかもしれませんが、補償アクションの情報はどんな価値でもあります。
佐賀に関しては、私自身が知る限り、すべてが正しい。あなたは佐賀を状態機械のように考えるべきです。それだけです。
それはサガが集合体に何かをするように命じるコマンドです。このアクションのイベントがあります。このイベントは、必要な修正アクションの場合もあれば、ビューで非正規化して、何をすべきかを決定するために一部のユーザーに表示されるようにする必要がある場合もあります。
それはあなたのビジネスルールに依存します。簡単な修正があります:集約ルートはそのような場合にそれを行うか、または選択が複雑すぎてプログラムで実行できない(開発コストが高すぎる)ことを知っているため、これをあるユーザーに提案することができます。異なるアクションから選択する場合があります。すべては、補償アクションのコンテキストに依存します。これは純粋なビジネスルールです。この場合、またはその場合に何をすべきか。これは、ドメインエキスパートに尋ねて、自動ソリューションを開発する方が良いか、またはソリューションがユーザーRonald R.に尋ねることであるかを彼と一緒に選択するものです。
完全を期すために、状態を元に戻す方法について、Martin Fowlerからの関連スニペットを含めると考えました。
自分自身を前方に再生するイベントだけでなく、自分自身を逆にできることもしばしば役立ちます。
反転は、イベントが差分の形でキャストされる場合に最も簡単です。この例は、「マーティンのアカウントを$ 110に設定する」ではなく、「マーティンのアカウントに$ 10を追加する」です。前者の場合、$ 10を引くだけで元に戻すことができますが、後者の場合、アカウントの過去の価値を再現するのに十分な情報がありません。
入力イベントが差分アプローチに従わない場合、イベントは、処理中の反転に必要なすべてを確実に格納する必要があります。これを行うには、変更された値に以前の値を保存するか、イベントの差異を計算して保存します。
概念的に:
アプリケーションの状態を変更するイベントを発生させる別のコマンド(補正アクション)を実行することによってのみ、将来の状態を変更できます。
質問を「混乱させない」ために、「最後のイベントの削除」というこのフレーズについて考えてください。
つまり、CQRSパターン内のイベントを削除するオプションはありません。
スナップショットの状態(その状態に至るすべてのイベントに基づく)を作成することにより、イベントストアを縮小できますが、この物理的な側面はイベントの概念とは関係ありません。
Geert-Jan、私も補償アクションが対応するイベントを単に削除できると思います。これは理にかなっており、イベントソーシングデザインパターンのもう1つの利点である、補償トランザクションデザインパターンの実装の容易さを示しています。
イベントを削除すると、イベントソーシングまたはCQRSの「原則」に違反すると言う人もいます。それは限定的な一般化だと思います。キャンセルされているグローバルトランザクションのスコープ内で作成されたイベントを削除しても問題ないと思います。疑似コードを考えてみましょう:
try {
newEvents = processMycommand(myCommand)
for (Event newEvent : newEvents)
EventStore.insertEvent(newEvent);
} catch (Exception e) {
EventStore.rollback();
}
イベントストアがトランザクションデータベースであるとします。疑似コードでは、最初のイベントを挿入した状況を想像できますが、2番目のイベントを挿入しようとすると、例外がスローされました。 rollbackコマンドは、最初のイベントの挿入を元に戻します。それは合理的ですか?
ACIDデータベーストランザクション(コミット/ロールバックを伴うトランザクション)が妥当である場合、補正トランザクションが妥当でないのはなぜですか?
グローバルSagaトランザクションを実行すると、データの変更を元に戻すことができます(補正により)。トランザクションが完了しなかったため、トランザクション中に作成されたイベントを保持する必要はありません。
これで、補正がイベントを削除しようとして、そのイベントがオブジェクトの最新のイベントではない場合、削除は発生しません。しかし、一般的には、特に読み取り集中型のソリューションでは、そうなる可能性はほとんどありません。
イベントストレージは保存したいデータにすぎないと考えてみましょう。たとえば、ハードドライブを用意し、最初からデータを書き込むことができます。イベントを取得するたびに、以前のデータを追加するので、前回停止したディスクに書き込みを続けます。イベントを削除する場合は、戻ってその部分をディスクから削除し、ギャップを残します。自分で戻ると、イベントストレージの速度が低下しますが、それでも問題ありません。ファイルシステムを使用する場合、ギャップを後者のイベントで埋めようとするため、ストレージの断片化が遅くなるか、デフラグを実行できます。どちらも私たちが好きなものではありません。データベースについて話している場合、イベントを格納するために追加専用データベースの代わりにリレーショナルデータベースを使用すると、次のようになります。
ref: https://cambridge-intelligence.com/bringing-time-series-data-to-life-with-keylines/
Ofc。通常のサイトではこれは問題ではありませんが、これらのソリューションはfacebookやgoogleなどの巨大なWebサイト用に設計されています...つまり、追加のみのデータベースでイベントを削除する方法と、タイムマシンを構築し、時間を遡ってイベントを変更または防止するようなものを報酬と呼びますか???
私の知る限り。これを解決する唯一の方法は、不要なイベントを除外する新しいイベントストレージを作成し、その後古いイベントストレージを削除することです。しかし、これは単一のイベントを削除するための極端な解決策です。 GDPRについて話している場合、私が知っている唯一の比較的良いソリューションは、イベントストレージに暗号化された個人データを保存し、別のデータベースから暗号化キーを削除することです。