6.1.1 传统持久化技术的问题
传统的持久化技术将类映射到数据库表, 将这些类的字段映射到数据表中的列, 将这些类的实例映射到数据表中的行.
弊端:
对象与关系的 “阻抗失调”
关系型数据的表格结构模式, 与领域模型及其复杂关系的图状结构之间, 存在基本的概念不匹配问题.
- ORM 是否有效
缺乏聚合的历史
- 监管
- 安全
实施审计功能将非常烦琐且容易出错
- 耗时
- 记录审计日志的代码可能会和业务逻辑代码发生偏离
事件发布是凌驾于业务逻辑之上
- 不支持发布领域事件
- 无法把自动发布消息作为更新数据库事务的一部分
6.1.2 什么是事件溯源
事件溯源是一种一事件为中心的技术, 用于实现业务逻辑和聚合的持久化.
- 聚合作为一系列事件存储在数据库中
- 每个事件代表聚合的状态变化
记录变更.
事件溯源通过事件来持久化聚合
事件存储:
- EVENTS 表
从事件存储中加载聚合的步骤:
- 加载聚合事件
- 使用其默认构造函数创建聚合实例
- 调用 apply() 方法遍历事件
apply() 就是事件的 handler.
事件代表状态的改变
每当聚合的状态发生变化时, 它必须发出一个事件.
- 为了持久化, 可溯源
聚合方法都和事件相关
事件溯源框架: Eventuate Client
- process() 方法将包含更新请求的命令对象作为参数, 并返回事件列表
- apply() 方法将事件作为参数, 并返回空 (VOID)
事件可能来自调用方, 也可能来自源自身?
创建聚合的步骤:
更新聚合的步骤:
基于事件溯源的 Order 聚合
6.1.3 使用乐观锁处理并发更新
乐观锁通常使用版本列来检测聚合自读取以来是否已更改.
6.1.4 事件溯源和发布事件
在事件存储库中保存事件本质上是一个原子化的操作.
一个系统操作可能对应多个事件, 这些事件的存储应该是原子的.
使用轮询发布事件
轮询 EVENTS 表:
- 利用 event_id 来标记进度
- 会漏事件
解决方案:
- 添加新列, 标记是否 publish
使用事务日志拖尾技术来可靠地发布事件
从数据库事务日志中读取插入 EVENTS 表的事件, 并将它们发布到消息代理.