java - 在均匀采购模式中处理状态更新

标签 java microservices event-sourcing

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

用例:

  1. 已生成金额为 100 美元且状态为审核中的发票。
  2. 然后发票状态更新为billed
  3. 然后支付 50 美元,调整 20 美元,状态更新为已支付
  4. 我们后来意识到金额不正确。所以我们想回滚之前的交易并将账单状态恢复为重新开单
  5. 然后我们将支付 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 包含有关付款、调整和状态更改的信息

这是我的问题

  1. 我知道余额是如何反转的,但我不知道我们如何才能对状态实现同样的效果
  2. 另外,如果 api 调用(命令)因上述事件发生故障,我将如何处理。 IE
    • 第 3 步调用服务
    • 然后是第5步
    • 然后是第 4 步。

据我所知,余额没有问题,但发票状态不正确。

请告诉我如何最好地处理事件溯源模式。

最佳答案

I get how balances can be reversed but I do not see how we can accomplish the same effect for status

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

根据我在此处看到的情况,我预计会发生逆转,从而使状态再次变为已结算。我们认为它已支付,但该条目是错误的,因此我们会将对象恢复到之前的状态。

如果那是正确的,那么我们的状态将是Billed

但它可能不是——这不是撤消,而是您域中的一种行为。这可能会将域移动到状态机以前未发现的部分。

how will I handle if api calls(commands) come out of order for the above events.

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

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

如果您担心如果命令出现乱序会得到“错误”的历史记录,那么您需要阅读并整合 Udi Dahan 的文章 Race Conditions Don't Exist

A microsecond difference in timing shouldn’t make a difference to core business behaviors.

关于java - 在均匀采购模式中处理状态更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49944789/

相关文章:

java - 如何检测方法发布中同一时间的重复请求

java - 用 jsonpath 替换 json 值

haskell - Haskell 中的强类型事件

c# - CQRS 写入端 DDD 中的时间序列/时间数据

java - 打开 zip 文件时出错或缺少 : build/tmp/expandedArchives/org. jacoco.agent 的 JAR list

java - 如果源目标相同,Java 中的 fileoutputstream 生成零字节?

authentication - 如何跨多个微服务提供用户身份?

spring-boot - Istio 服务发现

java - 微服务中的外部URL配置

C# 检测在运行时第二次运行应用程序期间更改了哪些 C# (.cs/poco) 文件