为什么在事件采购模式中的事件流?

时间:2018-04-24 20:29:37

标签: java domain-driven-design microservices event-sourcing

希望确保我能够清楚地随意剥离东西。

EVENT STORE数据库

| p_key | invoice_id | Event type        | Version | Data |
|-------|------------|-------------------|---------|------|
| 1     | 41234      | Invoice_Generated | 1       | JSON |
| 2     | 34241      | Invoice_Generated | 1       | JSON |
| 3     | 12345      | Invoice_Generated | 1       | JSON |
| 4     | 12345      | Invoice_Reviewed  | 2       | JSON |
| 5     | 12345      | Invoice_Paid      | 3       | JSON |

JAVA侧面组件

  1. 活动商店:
  2. 活动流
  3. 事件
  4. 事件存储负责检索事件列表,并在完成所有操作后将事件保存到数据库。

    public interface EventStore {
        EventStream loadEventStream(AggregateId aggregateId);
        void store(AggregateId aggregateId, long version, List<Event> events);
    
    }
    

    事件基本上是从数据库中检索到的行之一。

    public interface Event<T> {
        AggregateId getAggregateId();
    
        int getVersion();
    
        String getEventType();
    
        void applyOn(T account);
    }
    

    我没有得到的是事件流的使用。对我来说,为什么我需要一个事件流

    是没有意义的
    public interface EventStream extends Iterable<Event> {
        long version();
    
        void addAll(List<Event> changes);
    }
    

    事件流的唯一目的是能够迭代那些听起来不那么有用的事件列表,也许我错过了一些东西,但为什么我不能摆脱事件流并将其称为一天?

    来源:https://github.com/Pragmatists/eventsourcing-java-example/tree/excercise_1_solution/eventsourcing/src/main/java/com/pragmatists/eventsourcing

2 个答案:

答案 0 :(得分:1)

这个问题是关于事件源的非常低级别的视图,并且很大程度上取决于事件存储的实际实现。总而言之,我可以给你一个答案,希望能够了解你对事件商店的理解。

  

事件流的唯一目的是能够迭代那些听起来不那么有用的事件列表,也许我错过了一些东西,但为什么我不能摆脱事件流并将其称为一天?

是的,事件流提供了迭代可能的大型事件列表的方法,而不是以阻塞的方式从事件存储中检索所有事件。通常,它仅用于读取事件,因此其接口不包含将事件追加到事件存储的方法。

因此,客户端代码只需要来自流的事件。

将事件添加到事件存储时,为了防止并发写入,需要传递事件流的预期版本。可以通过对方法version使用EventStore.appendEvents(expectedVersion, newEvents)参数来执行此操作,或者它可以传递先前加载的事件流,并让Event存储检索最后看到的version,从而减​​少耦合客户端代码实际执行事件流锁定机制。因此,附加方法的签名可能是这样的:

EventStore.appendEvents(previousEventStream, newEvents)

因此,客户端代码不知道/关心事件存储使用哪种锁定机制(乐观或悲观)来防止并发写入。

可以找到一个例子here (免责声明:它是我的)

public function appendEventsForAggregate(AggregateDescriptor $aggregateDescriptor, $eventsWithMetaData, AggregateEventStream $expectedEventStream): void;

答案 1 :(得分:0)

根据JSON字段中包含的数据的丰富程度,可以执行各种有趣的流处理形式-例如计算每个客户的生命周期价值(当您遍历每个事件时,不断汇总特定客户的总支出),按类别进行支出汇总(与上述情况相同,每个项目类别仅进行汇总)等。将数据作为流进行处理有助于构建数据生命周期以及窗口抽象(滑动/固定宽度)。