【问题标题】:Read-Side DB eventual Consistency with Event Handlers. How to segment read side updates读取端数据库最终与事件处理程序保持一致。如何分段读取端更新
【发布时间】:2018-07-09 17:24:38
【问题描述】:

我已经实现了一个事件存储系统,其中我的根聚合以仓库为模型。例如,我有一些事件,例如 BoxCreatedBoxLocationChanged。这两个事件都有单独的事件处理程序来更新读取边表dbo.Boxes

但是,我现在已经到了这两个处理程序都需要更新另一个读取端 DB dbo.BoxType 的地步,它跟踪每个盒子类型的库存状态和位置。

我的问题是我是否应该为这些新的读取端更新创建一个单独的事件处理程序(使用相同的事件),还是应该将另一个存储库注入当前事件处理程序并在同一事件中处理所有读取端更新处理程序?

哪个是首选的设计选择?选择是否取决于我未列出的其他因素?

为了演示,使用 MediatR,我目前有如下事件处理程序:

public class BoxCreatedHandler : INotificationHandler<BoxCreated>
{
    private readonly IBoxRepository _repo;

    public BoxCreatedHandler(IBoxRepository repo)
    {
        _repo = repo;
    }

    public async Task Handle(BoxCreated e, CancellationToken ct)
    {
        Box b = JsonConvert.DeserializeObject<Box>(e.Data);
        _repo.CreateBox(b);

        // QUESTION: do I just go ahead and do my stock and location update here using another injected repo? 
        // Or should I register another handler for this event that does the update?

        // todo: how to handle read db update errors here? Will need to queue a aggregate replay to rebuild the read db?
    }
}

如果您能就如何处理读取端更新失败为我指明正确的方向,将获得奖励。

谢谢!

【问题讨论】:

    标签: c# cqrs event-sourcing eventual-consistency mediatr


    【解决方案1】:

    这取决于可以触发框类型更改的因素。如果框类型更改仅在另一个事件的上下文中进行,则应在此事件处理程序内更新读取模型。如果有专门用于更改框类型的工作流,则应通过新事件和处理程序使用该工作流,以便所有框类型更改都经过相同的逻辑。

    我不喜欢在同一个有界上下文中为同一个事件使用多个处理程序,因为这会让人感到困惑。处理程序可能会乱序触发,从而导致难以发现的业务逻辑问题。

    在您发布的另一个问题中,您讨论了批量创建框并为每个框生成创建和移动消息。根据您的事件存储,如果创建事件导致框类型更改事件,而移动事件导致不同的框类型更改事件,则这些事件可能不会以正确的顺序到达。事件的顺序取决于事件日志引擎(Kafka 与 Kinesis 不同,Event Hub 也不同),因此您必须注意其工作原理,以确保该框以正确的类型结束。

    【讨论】:

      猜你喜欢
      • 2018-12-20
      • 1970-01-01
      • 2017-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-10
      • 1970-01-01
      相关资源
      最近更新 更多