イベント ソーシング パターンEvent Sourcing pattern

ドメインに、データの現在の状態だけを格納する代わりに、追加専用ストアを使用して、そのデータに対して実行された一連のすべてのアクションを記録します。Instead of storing just the current state of the data in a domain, use an append-only store to record the full series of actions taken on that data. ストアは、レコードのシステムとして機能し、ドメイン オブジェクトを具体化するために使用できます。The store acts as the system of record and can be used to materialize the domain objects. これにより、データ モデルとビジネス ドメインの同期の必要性を避けることで、パフォーマンス、スケーラビリティ、および応答性を向上させながら、複合ドメインでのタスクを簡略化できます。This can simplify tasks in complex domains, by avoiding the need to synchronize the data model and the business domain, while improving performance, scalability, and responsiveness. さらに、トランザクション データの整合性を提供し、補正アクションを有効にできる完全な監査証跡と履歴を保持することもできます。It can also provide consistency for transactional data, and maintain full audit trails and history that can enable compensating actions.

コンテキストと問題Context and problem

ほとんどのアプリケーションはデータを操作します。またアプリケーションの一般的なアプローチは、ユーザーがデータを操作したら、データを更新して、データの最新の状態を維持することです。Most applications work with data, and the typical approach is for the application to maintain the current state of the data by updating it as users work with it. たとえば、従来の作成、読み取り、更新、および削除 (CRUD) モデルでの一般的なデータ処理は、ストアからデータを読み取り、何らかの変更を行い、(多くの場合にデータをロックするトランザクションを使用して) データの現在の状態を新しい値で更新することです。For example, in the traditional create, read, update, and delete (CRUD) model a typical data process is to read data from the store, make some modifications to it, and update the current state of the data with the new values—often by using transactions that lock the data.

CRUD アプローチにはいくつかの制限があります。The CRUD approach has some limitations:

  • CRUD システムは、データ ストアに対して直接更新操作を実行しますが、これにより、必要とする処理オーバーヘッドのためにパフォーマンスと応答性が低下し、スケーラビリティが制限される可能性があります。CRUD systems perform update operations directly against a data store, which can slow down performance and responsiveness, and limit scalability, due to the processing overhead it requires.

  • 多くの同時実行ユーザーがいるコラボレーション ドメインでは、更新操作がデータの単一のアイテムに対して行われるため、データ更新の競合が発生する可能性が高まります。In a collaborative domain with many concurrent users, data update conflicts are more likely because the update operations take place on a single item of data.

  • 各操作の詳細を個別のログに記録する追加の監査メカニズムがない限り、履歴が失われます。Unless there's an additional auditing mechanism that records the details of each operation in a separate log, history is lost.

CRUD アプローチの制限の詳細については、余裕がある場合にのみ CRUD を使用する方法に関するページをご覧ください。For a deeper understanding of the limits of the CRUD approach, see CRUD, Only When You Can Afford It.

解決策Solution

イベント ソーシング パターンは、一連のイベントによって制御されるデータへの操作の処理方法を定義し、各イベントが追加専用のストアに記録されます。The Event Sourcing pattern defines an approach to handling operations on data that's driven by a sequence of events, each of which is recorded in an append-only store. アプリケーション コードは、データに対して発生した各アクションを強制的に記述する一連のイベントをイベント ストアに送信し、そこでそれらが保持されます。Application code sends a series of events that imperatively describe each action that has occurred on the data to the event store, where they're persisted. 各イベントは、データに対する一連の変更を表します (AddedItemToOrder など)。Each event represents a set of changes to the data (such as AddedItemToOrder).

イベントは、データの現在の状態に関するレコードのシステム (権限のあるデータ ソース) として機能するイベント ストアに保持されます。The events are persisted in an event store that acts as the system of record (the authoritative data source) about the current state of the data. イベント ストアは、一般にこれらのイベントを公開し、コンシューマーが通知を受け取り、必要に応じてそれらを処理できるようにします。The event store typically publishes these events so that consumers can be notified and can handle them if needed. コンシューマーはたとえば、イベント内の操作を他のシステムに適用するタスクを開始したり、操作を実行するために必要なその他の関連アクションを実行したりすることができます。Consumers could, for example, initiate tasks that apply the operations in the events to other systems, or perform any other associated action that's required to complete the operation. イベントを生成するアプリケーション コードは、イベントにサブスクライブするシステムから分離されていることに注意してください。Notice that the application code that generates the events is decoupled from the systems that subscribe to the events.

イベント ストアによって公開されているイベントの一般的な用途は、アプリケーションのアクションによってエンティティが変更されたとき、および外部システムとの統合のために、エンティティの具体化されたビューを保持することです。Typical uses of the events published by the event store are to maintain materialized views of entities as actions in the application change them, and for integration with external systems. たとえば、システムは、UI の一部の入力に使用されるすべての顧客注文の具体化されたビューを保持できます。For example, a system can maintain a materialized view of all customer orders that's used to populate parts of the UI. アプリケーションが新しい注文を追加したり、注文の商品を追加または削除したり、出荷情報を追加したりすると、これらの変更を記述するイベントを処理し、使用して、具体化されたビューを更新できます。As the application adds new orders, adds or removes items on the order, and adds shipping information, the events that describe these changes can be handled and used to update the materialized view.

また、いつでも、アプリケーションでイベントの履歴を読み取り、それを使用して、エンティティに関連するすべてのイベントを再生し、使用することで、そのエンティティの現在の状態を具体化できます。In addition, at any point it's possible for applications to read the history of events, and use it to materialize the current state of an entity by playing back and consuming all the events related to that entity. これは、要求の処理時またはスケジュールされたタスクによって、オンデマンドでドメイン オブジェクトを具体化するために行うことができるため、プレゼンテーション層をサポートするために、エンティティの状態を具体化されたビューとして保存できます。This can occur on demand to materialize a domain object when handling a request, or through a scheduled task so that the state of the entity can be stored as a materialized view to support the presentation layer.

図は、具体化されたビューの作成、外部アプリケーションおよびシステムとのイベントの統合、特定のエンティティの現在の状態のプロジェクションを作成するためのイベントの再生などのイベント ストリームを使用する場合のいくつかのオプションを含む、パターンの概要を示しています。The figure shows an overview of the pattern, including some of the options for using the event stream such as creating a materialized view, integrating events with external applications and systems, and replaying events to create projections of the current state of specific entities.

イベント ソーシング パターンの概要と例

イベント ソーシング パターンには次の利点があります。The Event Sourcing pattern provides the following advantages:

  • イベントは不変であり、追加専用の操作を使用して保存できます。Events are immutable and can be stored using an append-only operation. イベントを開始したユーザー インターフェイス、ワークフロー、またはプロセスは続行でき、イベントを処理するタスクはバック グラウンドで実行できます。The user interface, workflow, or process that initiated an event can continue, and tasks that handle the events can run in the background. これと、トランザクションの処理中に競合が発生しないことの組み合わせにより、特にプレゼンテーション レベルやユーザー インターフェイスで、アプリケーションのパフォーマンスとスケーラビリティが大幅に向上する可能性があります。This, combined with the fact that there's no contention during the processing of transactions, can vastly improve performance and scalability for applications, especially for the presentation level or user interface.

  • イベントは、イベントによって表されるアクションを記述するために必要な関連データと共に、発生したいくつかのアクションを記述する単純なオブジェクトです。Events are simple objects that describe some action that occurred, together with any associated data required to describe the action represented by the event. イベントは直接データ ストアを更新しません。Events don't directly update a data store. それらは、適時に処理するために記録されるだけです。They're simply recorded for handling at the appropriate time. これにより、実装と管理が簡単になる可能性があります。This can simplify implementation and management.

  • イベントは一般にドメイン専門家にとって意味がありますが、オブジェクトリレーショナル インピーダンス ミスマッチにより、データベース テーブルが複雑になり、理解しにくくなる可能性があります。Events typically have meaning for a domain expert, whereas object-relational impedance mismatch can make complex database tables hard to understand. テーブルは発生したイベントを表すのではなく、システムの現在の状態を表す人工的な構造物です。Tables are artificial constructs that represent the current state of the system, not the events that occurred.

  • イベント ソーシングは、データ ストア内のオブジェクトを直接更新する必要性を避けるため、同時更新による競合の発生を防ぐのに役立つ可能性があります。Event sourcing can help prevent concurrent updates from causing conflicts because it avoids the requirement to directly update objects in the data store. ただし、ドメイン モデルは、不整合な状態になる可能性がある要求から、それ自体を保護するように設計する必要があります。However, the domain model must still be designed to protect itself from requests that might result in an inconsistent state.

  • イベントの追加専用記憶域は、データ ストアに対して実行されるアクションを監視し、いつでもイベントを再生することによって、具体化されたビューまたはプロジェクションとして、現在の状態を再生成し、システムのテストおよびデバッグに役立てるために使用できる監査証跡を提供します。The append-only storage of events provides an audit trail that can be used to monitor actions taken against a data store, regenerate the current state as materialized views or projections by replaying the events at any time, and assist in testing and debugging the system. さらに、変更を取り消すために補正イベントを使用するという要件は、元に戻された変更の履歴を提供しますが、これはモデルが現在の状態を保存しただけの場合には当てはまりません。In addition, the requirement to use compensating events to cancel changes provides a history of changes that were reversed, which wouldn't be the case if the model simply stored the current state. イベントのリストは、アプリケーションのパフォーマンスを分析したり、ユーザーの動作傾向を検出したり、またはその他の有益なビジネス情報を取得したりするために使用することもできます。The list of events can also be used to analyze application performance and detect user behavior trends, or to obtain other useful business information.

  • イベント ストアがイベントを発生し、タスクがそれらのイベントに対応して操作を実行します。The event store raises events, and tasks perform operations in response to those events. このイベントからのタスクの分離により、柔軟性と拡張性を提供します。This decoupling of the tasks from the events provides flexibility and extensibility. タスクは、イベントの種類とイベント データを認識しますが、イベントをトリガーした操作を認識しません。Tasks know about the type of event and the event data, but not about the operation that triggered the event. さらに、複数のタスクで、各イベントを処理することができます。In addition, multiple tasks can handle each event. これにより、イベント ストアによって生成された新しいイベントのみをリッスンする他のサービスやシステムと簡単に統合できます。This enables easy integration with other services and systems that only listen for new events raised by the event store. ただし、イベント ソーシング イベントは、きわめて低いレベルになる傾向があるため、代わりに特定の統合イベントを生成する必要がある可能性があります。However, the event sourcing events tend to be very low level, and it might be necessary to generate specific integration events instead.

イベント ソーシングは、イベントに対応して、データ管理タスクを実行することによって、および保存されたイベントからビューを具体化することによって、一般的に CQRS パターンと組み合わされます。Event sourcing is commonly combined with the CQRS pattern by performing the data management tasks in response to the events, and by materializing views from the stored events.

問題と注意事項Issues and considerations

このパターンの実装方法を決めるときには、以下の点に注意してください。Consider the following points when deciding how to implement this pattern:

システムは、イベントを再生することによって、具体化されたビューを作成するか、データのプロジェクションを生成するときに、最終的にのみ整合されます。The system will only be eventually consistent when creating materialized views or generating projections of data by replaying events. 要求の処理の結果としてイベント ストアにイベントを追加するアプリケーション、公開されるイベント、およびそれらを処理するイベントのコンシューマー間にはいくらかの遅延が発生します。There's some delay between an application adding events to the event store as the result of handling a request, the events being published, and consumers of the events handling them. この期間に、エンティティへの追加の変更を記述する新しいイベントがイベント ストアに到着している可能性があります。During this period, new events that describe further changes to entities might have arrived at the event store.

注意

結果整合性に関する情報については、「Data consistency primer」 (データ整合性入門) をご覧ください。See the Data Consistency Primer for information about eventual consistency.

イベント ストアは情報の永続的なソースであるため、イベント データが更新されてはなりません。The event store is the permanent source of information, and so the event data should never be updated. エンティティを更新して、変更を元に戻す唯一の方法は、補正イベントをイベント ストアに追加することです。The only way to update an entity to undo a change is to add a compensating event to the event store. おそらく移行時に、永続化されたイベントの形式 (データはなく) を変更する必要がある場合、ストア内の既存のイベントと新しいバージョンを結合することが難しい可能性があります。If the format (rather than the data) of the persisted events needs to change, perhaps during a migration, it can be difficult to combine existing events in the store with the new version. 変更を行うすべてのイベントを、新しい形式に準拠するように反復処理するか、新しい形式を使用する新しいイベントを追加する必要がある可能性があります。It might be necessary to iterate through all the events making changes so they're compliant with the new format, or add new events that use the new format. 新旧両方のイベント形式を維持するには、イベント スキーマの各バージョンのバージョン スタンプを使用することを検討してください。Consider using a version stamp on each version of the event schema to maintain both the old and the new event formats.

マルチスレッド アプリケーションとアプリケーションの複数インスタンスがイベント ストアにイベントを保存する可能性があります。Multi-threaded applications and multiple instances of applications might be storing events in the event store. イベント ストア内のイベントの整合性は重要であり、特定のエンティティに影響するイベントの順序も重要です (エンティティに対して発生した変更の順序は、その現在の状態に影響します)。The consistency of events in the event store is vital, as is the order of events that affect a specific entity (the order that changes occur to an entity affects its current state). すべてのイベントにタイムスタンプを追加すると、問題の回避に役立ちます。Adding a timestamp to every event can help to avoid issues. 別の一般的な方法は、要求の結果としての各イベントに、増分識別子で注釈を付けることです。Another common practice is to annotate each event resulting from a request with an incremental identifier. 2 つのアクションが同時に同じエンティティについてのイベントを追加しようとした場合に、イベント ストアは、既存のエンティティ識別子およびイベント識別子に一致するイベントを拒否できます。If two actions attempt to add events for the same entity at the same time, the event store can reject an event that matches an existing entity identifier and event identifier.

イベントを読み取って情報を取得するための標準のアプローチや SQL クエリのような既存のメカニズムはありません。There's no standard approach, or existing mechanisms such as SQL queries, for reading the events to obtain information. 抽出できる唯一のデータは、条件としてイベント識別子を使用するイベントのストリームです。The only data that can be extracted is a stream of events using an event identifier as the criteria. イベント ID は一般に個別のエンティティにマップします。The event ID typically maps to individual entities. エンティティの現在の状態は、そのエンティティの元の状態に照らして、それに関連するすべてのイベントを再生することによってのみ判断できます。The current state of an entity can be determined only by replaying all of the events that relate to it against the original state of that entity.

各イベント ストリームの長さは、システムの管理と更新に影響します。The length of each event stream affects managing and updating the system. ストリームが大きい場合、指定した数のイベントなどの特定の間隔でスナップショットを作成することを検討してください。If the streams are large, consider creating snapshots at specific intervals such as a specified number of events. エンティティの現在の状態は、スナップショットから、および特定の時点以降に発生したイベントを再生することにより、取得できます。The current state of the entity can be obtained from the snapshot and by replaying any events that occurred after that point in time. データのスナップショットの作成の詳細については、Martin Fowler のエンタープライズ アプリケーション アーキテクチャのスナップショット Web サイトと「Master-Subordinate Snapshot Replication」 (マスター/従属スナップショット レプリケーション) をご覧ください。For more information about creating snapshots of data, see Snapshot on Martin Fowler’s Enterprise Application Architecture website and Master-Subordinate Snapshot Replication.

イベント ソーシングは、データへの更新の競合の可能性を最小にしますが、それでもなおアプリケーションでは結果整合性とトランザクションの欠如の結果としての不整合を処理できる必要があります。Even though event sourcing minimizes the chance of conflicting updates to the data, the application must still be able to deal with inconsistencies that result from eventual consistency and the lack of transactions. たとえば、その商品の注文が行われている間に、在庫ストックの減少を示すイベントがデータ ストアに到着したため、結果として顧客にアドバイスするか、取り寄せ注文を作成することによって、2 つの操作を調整する要件が発生することがあります。For example, an event that indicates a reduction in stock inventory might arrive in the data store while an order for that item is being placed, resulting in a requirement to reconcile the two operations either by advising the customer or creating a back order.

イベントの公開は「少なくとも 1 回」になる可能性があるため、イベントのコンシューマーはべき等である必要があります。Event publication might be "at least once," and so consumers of the events must be idempotent. それらは、イベントが複数回処理される場合に、イベントに記述されている更新を再適用すべきではありません。They must not reapply the update described in an event if the event is handled more than once. たとえば、コンシューマーの複数のインスタンスが、発注の合計数などのエンティティのプロパティを保持し、集計する場合に、発注イベントが発生したときに、1 つのインスタンスのみが集計の増分に成功する必要があります。For example, if multiple instances of a consumer maintain an aggregate an entity's property, such as the total number of orders placed, only one must succeed in incrementing the aggregate when an order placed event occurs. これは、イベント ソーシングの主要な特性ではありませんが、一般的な実装上の決定です。While this isn't a key characteristic of event sourcing, it's the usual implementation decision.

このパターンを使用する状況When to use this pattern

このパターンは、次のシナリオで使用します。Use this pattern in the following scenarios:

  • データ内のインテント、目的、または理由をキャプチャする場合。When you want to capture intent, purpose, or reason in the data. たとえば、顧客エンティティの変更を、転居アカウントの削除、または_死亡_などの一連の特定のイベントの種類として、キャプチャできます。For example, changes to a customer entity can be captured as a series of specific event types such as Moved home, Closed account, or Deceased.

  • データへの更新の競合の発生を最小限に抑えるか、完全に避けることが不可欠な場合。When it's vital to minimize or completely avoid the occurrence of conflicting updates to data.

  • 発生するイベントを記録したり、システムの状態を復元するためにそれらを再生できるようにしたり、変更をロールバックしたり、履歴および監査ログを記録したりする場合。When you want to record events that occur, and be able to replay them to restore the state of a system, roll back changes, or keep a history and audit log. たとえばタスクに、更新を元に戻すアクションを実行するために必要な複数のステップが含まれ、さらに、データを整合性のある状態に戻すいくつかのステップを再生する場合などです。For example, when a task involves multiple steps you might need to execute actions to revert updates and then replay some steps to bring the data back into a consistent state.

  • イベントの使用は、アプリケーションの操作の自然な機能であり、追加の開発や実装作業はほとんど必要ありません。When using events is a natural feature of the operation of the application, and requires little additional development or implementation effort.

  • これらのアクションを適用するために必要なタスクから、データの入力や更新のプロセスを分離する必要がある場合。When you need to decouple the process of inputting or updating data from the tasks required to apply these actions. これにより、UI パフォーマンスが向上したり、イベントが発生したときにアクションを実行する他のリスナーにイベントを配布したりすることができます。This might be to improve UI performance, or to distribute events to other listeners that take action when the events occur. たとえば、給与支払いシステムと経費提出 Web サイトを統合し、Web サイトで行われたデータ更新への対応で、イベント ストアによって発行されたイベントが、Web サイトと給与支払いシステムの両方で使用されるようにします。For example, integrating a payroll system with an expense submission website so that events raised by the event store in response to data updates made in the website are consumed by both the website and the payroll system.

  • 具体化されたモデルとエンティティ データの形式を変更できるようにする柔軟性が必要な場合、または —CQRS と組み合わせて使用する—場合は、データを公開する読み取りモデルまたはビューを適合させる必要があります。When you want flexibility to be able to change the format of materialized models and entity data if requirements change, or—when used in conjunction with CQRS—you need to adapt a read model or the views that expose the data.

  • CQRS と組み合わせて使用し、読み取りモデルの更新中に、結果整合性が許容できる場合、またはイベント ストリームからのエンティティおよびデータのリハイドレート中のパフォーマンスへの影響が許容できる場合。When used in conjunction with CQRS, and eventual consistency is acceptable while a read model is updated, or the performance impact of rehydrating entities and data from an event stream is acceptable.

このパターンは、次の状況では有効でない場合があります。This pattern might not be useful in the following situations:

  • 小規模または単純なドメイン、ビジネス ロジックがほとんどまたはまったく含まれていないシステム、または従来の CRUD データ管理メカニズムと自然にうまく連携する非ドメイン システム。Small or simple domains, systems that have little or no business logic, or nondomain systems that naturally work well with traditional CRUD data management mechanisms.

  • データのビューの整合性とリアルタイムの更新が必要なシステム。Systems where consistency and real-time updates to the views of the data are required.

  • 監査証跡、履歴、およびアクションをロールバックし、再生する機能が必要でないシステム。Systems where audit trails, history, and capabilities to roll back and replay actions are not required.

  • 基になるデータへの更新の競合の発生がきわめて少ないシステム。Systems where there's only a very low occurrence of conflicting updates to the underlying data. たとえば、データを更新せずに、ほとんどデータを追加するシステムなどです。For example, systems that predominantly add data rather than updating it.

Example

会議管理システムでは、可能性のある出席者が予約しようとするときに、席がまだ空いているかどうかを確認できるように、完了した会議の予約の数を追跡する必要があります。A conference management system needs to track the number of completed bookings for a conference so that it can check whether there are seats still available when a potential attendee tries to make a booking. システムでは、少なくとも 2 つの方法で、会議の予約の合計数を格納できます。The system could store the total number of bookings for a conference in at least two ways:

  • システムは、予約情報を保持するデータベース内の個別のエンティティとして、予約の合計数に関する情報を格納できます。The system could store the information about the total number of bookings as a separate entity in a database that holds booking information. 予約が行われるか、取り消されると、システムは必要に応じてこの数を増分または減分できます。As bookings are made or canceled, the system could increment or decrement this number as appropriate. このアプローチは理論上は単純ですが、多数の出席者が短時間に席を予約しようとした場合に、スケーラビリティの問題が発生する可能性があります。This approach is simple in theory, but can cause scalability issues if a large number of attendees are attempting to book seats during a short period of time. たとえば、予約期間が終わる前の最終日などです。For example, in the last day or so prior to the booking period closing.

  • システムは、イベント ストアに保持されるイベントとして、予約と取り消しに関する情報を格納できます。The system could store information about bookings and cancellations as events held in an event store. さらに、これらのイベントを再生することにより、空席数を計算できます。It could then calculate the number of seats available by replaying these events. このアプローチは、イベントの不変性のため、スケーラビリティが向上する可能性があります。This approach can be more scalable due to the immutability of events. システムは、イベント ストアからデータを読み取ったり、イベント ストアにデータを追加したりできる必要があるだけです。The system only needs to be able to read data from the event store, or append data to the event store. 予約と取り消しに関するイベント情報が変更されることはありません。Event information about bookings and cancellations is never modified.

次の図は、イベント ソーシングを使用して、会議管理システムの座席予約サブシステムを実装する方法を示しています。The following diagram illustrates how the seat reservation subsystem of the conference management system might be implemented using event sourcing.

会議管理システムで、座席予約に関する情報をキャプチャするためのイベント ソーシングの使用

2 つの座席を予約するためのアクションのシーケンスは次のようになります。The sequence of actions for reserving two seats is as follows:

  1. ユーザー インターフェイスは、2 名の出席者の座席を予約するコマンドを発行します。The user interface issues a command to reserve seats for two attendees. コマンドは、個別のコマンド ハンドラーによって処理されます。The command is handled by a separate command handler. ユーザー インターフェイスから分離され、コマンドとして投稿された要求の処理を担当するロジックの一部。A piece of logic that is decoupled from the user interface and is responsible for handling requests posted as commands.

  2. 予約と取り消しを示すイベントをクエリすることによって、会議のすべての予約に関する情報を含む集計が構築されます。An aggregate containing information about all reservations for the conference is constructed by querying the events that describe bookings and cancellations. この集計は、SeatAvailability と呼ばれ、集計内のデータのクエリと変更のメソッドを公開するドメイン モデル内に含まれます。This aggregate is called SeatAvailability, and is contained within a domain model that exposes methods for querying and modifying the data in the aggregate.

    考慮すべきいくつかの最適化は、スナップショットの使用 (集計の現在の状態を取得するために、すべてのイベントをクエリし、再生する必要がないように) とメモリ内に集計のキャッシュされたコピーを保持することです。Some optimizations to consider are using snapshots (so that you don’t need to query and replay the full list of events to obtain the current state of the aggregate), and maintaining a cached copy of the aggregate in memory.

  3. コマンド ハンドラーは、ドメイン モデルによって公開されたメソッドを呼び出し、予約を行います。The command handler invokes a method exposed by the domain model to make the reservations.

  4. SeatAvailability 集計は予約された座席数を格納するイベントを記録します。The SeatAvailability aggregate records an event containing the number of seats that were reserved. 次回にイベントに集計が適用されたときに、すべての予約を使用して、残席数が計算されます。The next time the aggregate applies events, all the reservations will be used to compute how many seats remain.

  5. システムは、イベント ストア内のイベントの一覧に新しいイベントを追加します。The system appends the new event to the list of events in the event store.

ユーザーが座席をキャンセルした場合、コマンド ハンドラーが座席取り消しイベントを生成し、それをイベント ストアに追加することを除いて、システムは同様のプロセスに従います。If a user cancels a seat, the system follows a similar process except the command handler issues a command that generates a seat cancellation event and appends it to the event store.

スケーラビリティのためのスコープの拡大に加えて、イベント ストアを使用することで、会議の予約と取り消しの完全な履歴または監査証跡も提供します。As well as providing more scope for scalability, using an event store also provides a complete history, or audit trail, of the bookings and cancellations for a conference. イベント ストア内のイベントは、正確なレコードです。The events in the event store are the accurate record. システムはイベントを簡単に再生し、任意の時点に状態を復元できるため、他の方法で集計を保持する必要はありません。There is no need to persist aggregates in any other way because the system can easily replay the events and restore the state to any point in time.

この例の詳細については、「Introducing Event Sourcing」 (イベント ソーシングの導入) をご覧ください。You can find more information about this example in Introducing Event Sourcing.

このパターンを実装する場合は、次のパターンとガイダンスも関連している可能性があります。The following patterns and guidance might also be relevant when implementing this pattern:

  • コマンド クエリ責務分離 (CQRS) パターンCommand and Query Responsibility Segregation (CQRS) pattern. CQRS 実装についての情報の永続的なソースを提供する書き込みストアは、イベント ソーシング パターンの実装に基づくことがあります。The write store that provides the permanent source of information for a CQRS implementation is often based on an implementation of the Event Sourcing pattern. 個別のインターフェイスを使用して、データを更新する操作から、アプリケーションでデータを読み取る操作を分離する方法について説明します。Describes how to segregate the operations that read data in an application from the operations that update data by using separate interfaces.

  • Materialized View Pattern (具体化されたビュー パターン)Materialized View pattern. イベント ソーシングに基づいて、システムで使用されるデータ ストアは、一般に効率的なクエリに適していません。The data store used in a system based on event sourcing is typically not well suited to efficient querying. 代わりに、一般的なアプローチは、一定の間隔で、またはデータが変更されたときに、データの事前設定済みのビューを生成することです。Instead, a common approach is to generate prepopulated views of the data at regular intervals, or when the data changes. この実行方法を示します。Shows how this can be done.

  • Compensating Transaction パターンCompensating Transaction pattern. イベント ソーシング ストア内の既存のデータは更新されず、代わりにエンティティの状態を新しい値に切り替える新しいエントリが追加されます。The existing data in an event sourcing store is not updated, instead new entries are added that transition the state of entities to the new values. 変更を元に戻すには、単純に以前の変更を元に戻すことができないため、補正エントリを使用します。To reverse a change, compensating entries are used because it isn't possible to simply reverse the previous change. 以前の操作によって実行された作業を元に戻す方法について説明します。Describes how to undo the work that was performed by a previous operation.

  • Data consistency primer (データ整合性入門)Data Consistency Primer. 個別の読み取りストアまたは具体化されたビューでイベント ソーシングを使用すると、読み取られたデータはすぐに整合されるのではなく、最終的にのみ整合されます。When using event sourcing with a separate read store or materialized views, the read data won't be immediately consistent, instead it'll be only eventually consistent. 分散データの整合性の維持に関連する問題をまとめています。Summarizes the issues surrounding maintaining consistency over distributed data.

  • データのパーティション分割のガイダンスData Partitioning Guidance. イベント ソーシングを使用してスケーラビリティを向上させ、競合を少なくし、パフォーマンスを最適化する際に、データをパーティション分割することがあります。Data is often partitioned when using event sourcing to improve scalability, reduce contention, and optimize performance. データを個別のパーティションに分割する方法と発生する可能性がある問題について説明します。Describes how to divide data into discrete partitions, and the issues that can arise.