事件溯源-以事件為中心的編寫業務邏輯和持久化領域對象方法
1、事件溯源
事件溯源是一種事件為中心的技術,用于實現業務邏輯和聚合的持久化。聚合作為一系列事件存儲在數據庫中,每個事件代表聚合狀態的變化。
- 事件溯源通過事件來持久化聚合
- 事件代表狀態的變化
- 聚合方法都和事件相關(業務邏輯上通過聚合根上的命令方法來處理聚合的更新請求)
2、使用樂觀鎖處理并發更新
- 場景:兩個或更多的請求同時更新一個聚合
- 為了防止一個事務覆蓋另一個事務
- 示例:
update aggregate_root_table
set version = version + 1
where version = <original version>
3、事件溯源和事件發布
- 場景:如果事務A插入Event_ID為1010的事件,事務B插入EVENT_ID為1020的事件并且先提交。在事務A提交以前,事件發布者查詢事件并發布到消息代理,此時發布的事件為1020,此后事務A提交的1010的事件將不會被發布。
- 處理方式:增加一個發布狀態的字段
## 1、查詢未發布的事件
select * from events where published = 0 order by event_id ASC;
## 2、發布事件到消息代理
## 3、修改事件的標記
update events set published = 1 where event_id in ()
4、使用快照提升性能
- 場景:長生命周期的聚合可能會產生大量事件,隨著時間的推移,加載和重放這些事件的速度會越來越慢
-
處理方式:為事件表創建一個快照表,定期存儲快照。查詢時,只查詢快照事件以后的事件
image.png
Tabale: EVENTS
event_id | event_type | entity_type | entity_id | event_data |
---|---|---|---|---|
... | ... | User | e_01 | {...} |
103 | create | User | e_01 | {...} |
104 | update | User | e_01 | {...} |
105 | update | User | e_01 | {...} |
Tabale: SNAPSHOTS
event_id | event_type | entity_type | entity_id | snapshot_data |
---|---|---|---|---|
... | ... | ... | ... | ... |
103 | create | User | e_01 | {...} |
... | ... | ... | ... | ... |
5、冪等
- 在關系數據庫中檢測和丟棄重復消息
- 非關系數據庫,存儲處理消息的ID。驗證聚合的所有事件中是否包含此消息的ID
6、事件溯源的好處和弊端
- 好處:
可靠地發布領域事件
保留聚合歷史
為開發者提供一個“時光機” - 弊端:
編程模式有一定的學習曲線
基于消息傳遞的應用程序的復雜性
處理事件演化有一定難度
刪除數據庫存在一定難度
查詢事件存儲庫非常有挑戰性