Java 在均衡采购模式下处理状态更新

Java 在均衡采购模式下处理状态更新,java,microservices,event-sourcing,Java,Microservices,Event Sourcing,我正在寻找一种审计模式来保存实体的历史记录,我遇到了事件源模式。这是一个有趣的模式,其中大部分对我来说是有意义的,但是我有一个问题,关于如何实现特定的用例场景 用例: 已生成金额为100美元的发票,状态为“审核中” 然后,发票状态更新为“已开票” 然后支付50美元,调整20美元,状态更新为已支付 我们后来意识到金额不正确。因此,我们希望回滚上一个事务,并再次将账单状态恢复为账单状态 然后,我们支付70美元,调整20美元,并更新发票状态以完成 根据我对事件存储的理解。它应该只包含应用于实体的操作。

我正在寻找一种审计模式来保存实体的历史记录,我遇到了事件源模式。这是一个有趣的模式,其中大部分对我来说是有意义的,但是我有一个问题,关于如何实现特定的用例场景

用例:

  • 已生成金额为100美元的发票,状态为“审核中”
  • 然后,发票状态更新为“已开票”
  • 然后支付50美元,调整20美元,状态更新为已支付
  • 我们后来意识到金额不正确。因此,我们希望回滚上一个事务,并再次将账单状态恢复为账单状态
  • 然后,我们支付70美元,调整20美元,并更新发票状态以完成
  • 根据我对事件存储的理解。它应该只包含应用于实体的操作。因此,事件始终具有更新的交易金额(付款和调整)和状态

    数据库:

    发票:

    | id    | balance | payment | adjustment | status   |
    |-------|---------|---------|------------|----------|
    | 12345 | 10      | 70      | 20         | Paid     |
    
    事件存储:

    | event_id | invoice_id | Event            | Payload |
    |----------|------------|------------------|---------|
    | 1        | 12345      | Invoice_InReview | JSON    |
    | 2        | 12345      | Invoice_Billed   | JSON    |
    | 3        | 12345      | Invoice_Paid     | JSON    |
    | 4        | 12345      | Invoice_Reversed | JSON    |
    | 5        | 12345      | Invoice_Paid     | JSON    |
    
    JSON包含有关付款、调整和状态更改的信息

    下面是我的问题

  • 我知道平衡是如何逆转的,但我看不出我们如何才能实现地位的同样效果
  • 此外,如果上述事件的api调用(命令)出现问题,我将如何处理。即
    • 第三步呼叫服务
    • 然后第五步
    • 然后是第四步
  • 据我所知,余额将正常,但发票状态将不正确

    请告诉我如何最好地处理这一事件采购模式

    我知道平衡是如何逆转的,但我看不出我们如何才能实现地位的同样效果

    因此,首先要做的是与您的领域专家核实,以了解这种无处不在的语言是否具有发票状态在冲销和还款之间的概念

    根据我在这里看到的情况,我希望反转本身会再次将状态设置为billed。我们认为它已支付,但该条目是一个错误,因此我们会将对象恢复到其以前的状态

    如果这是正确的,那么我们的状态将是
    账单

    但它可能不是--这不是撤销,而是您的域内的行为。这可能会将域移动到状态机以前未发现的部分

    如果上述事件的api调用(命令)出现问题,我将如何处理

    这里可能隐藏着两个不同的问题——我将对每个问题进行总结

    如果你担心下游消费者对事件的反应,那么设计你的消费者是很重要的——如果他们需要了解整个历史,那么他们从历史中阅读。对历史记录中的更改作出反应的使用者将从事件存储中读取有序的历史记录,而不是对出现在消息传输中的消息作出反应。换句话说,发布的事件就像通知一样,告诉消费者刷新其历史记录副本

    如果您担心如果命令出现故障,您会得到“错误”的历史记录,那么您需要回顾并整合Udi Dahan的文章

    时间上的微秒差异不应该对核心业务行为产生影响


    “还有,如果事件以不同的顺序出现,我将如何处理”-它们从不出现顺序,不在同一个聚合中。您的事件存储不正常。它还应该包含事件的类型。事实上,它应该允许附加任何类型的事件。@ConstantinGalbenu由无序事件引起。我的意思是,对服务的api调用是无序的,即调用api进行支付,然后进行另一次支付,然后撤销第一次支付。我将为Clarity添加事件列。您的“事件”是指“命令”?您的事件存储应该只有以下列:
    event\u id、invoice\u id、event\u type、event\u payload
    。删除
    付款
    调整
    状态
    列。事件属性以适合您的格式(即json)在
    event\u payload
    列中序列化。因此,当一个命令到达您的发票时,您将加载所有事件,对它们进行反序列化,并将它们应用于发票实体。发票建立其内部状态(总金额和状态),然后处理该命令。因此,状态不是在EventStore中维护的,而是在内存中维护的。