领域事件和集成事件有什么区别? - DevCezz


在事件驱动架构的世界中,我们处理发送许多事件。然而,正如我们所知,尽管名称相同,但一件事并不总是等于另一件事。因此,为了区分这些事件,引入了两种名义类型的划分:领域事件和集成事件。

什么是领域事件?
按照其他开发者的说法,领域事件在同一个应用中是有效的。
这意味着它不会超出指定流程的边界。
对指定事件感兴趣的实体只需等待它发生并处理它。
这里没有消息代理或异步通信(尽管可能有一些),所有事件处理都发生在内存中。

这种方法给了我们在一个数据库事务中完成所有事情的惊人能力。

通过这种方式,我们可以松散地定义应用程序模块,并在出现异常时立即补偿给定命令的后果。

在 Spring 的情况下,我们然后在事件侦听@Async器的方法上使用注释。
但是选择这条路径,我们失去了一个数据库事务的优势,这在文档中有描述:

@Transactional通常与由 管理的线程绑定事务一起工作PlatformTransactionManager,将事务公开给当前执行线程中的所有数据访问操作。注意:这不会传播到方法内新启动的线程。

在我看来,用户 TriS 在 StackOverflow 上对这个问题的解释甚至更好。

但是当我们的应用程序需要通知其他应用程序有关某些事件的情况时呢?

什么是集成事件?
顾名思义,集成就是用来和外部其他单元进行集成的。
在这种情况下,我们已经超越了应用程序的边界,因此不存在数据库事务(至少是简单事务)的问题。
这个过程开始涉及需要异步通信和消息代理。

在我看来,这些仍然是领域事件,所以更好的名称应该是前面提到的 Kamil Grzybek 提供的提案,即领域事件通知。

内部和外部事件概念
我们的应用程序内部和外部都处理了事件,因此使用名称“内部事件”和“外部事件”可能是个好主意。

这可以比作私有方法和公共方法的概念:通过这种方式,我们可以快速确定哪些事件是我们的,哪些是我们暴露给外部其他团队的。

集成事件的启发式
另一个可能被问到的问题是如何从域事件中选择集成事件/外部事件?毕竟,我们不想在外部共享需要频繁更改的内容。以下 3 种启发式方法可以帮助我们解决这个问题。

1、稳定
您必须仔细聆听领域专家告诉我们的内容。如果我们发现一个经常与两个应用程序的名称相关联的领域词,那么它可能是集成事件的稳定候选者。

2、达成共识
每个界定的语境上下文都有自己的领域语言,但它们之间也有共享词汇的空间。因此,在创建集成事件之前,您需要三思,对于感兴趣的应用程序是否意味着相同。

3、满足客户要求
这不是关于业务客户端,而是关于我们应用程序的客户端,例如另一个微服务。如果多次报告给定事件的需求,则它可能是集成事件的候选者。

使用发件箱模式
这里还值得回顾一下发件箱模式。由于集成事件不在同一个数据库事务中运行,为了不丢失它们,使用CDC发件箱 等工具来帮助自己。