
52
|
第
4
章
起包裹在一个事务中,这样出现任何失败都能保证数据在两个表之间的一致性。同时,一
个独立的应用程序线程或进程会持续地轮询发件箱表,并向对应的事件流生成数据。一旦
成功生成数据,就删除在发件箱表中的对应记录。如果发生任何失败(无论是数据存储、
消费者
/
生产者还是事件代理本身)
,发件箱记录仍将保留,不会有丢失数据的风险。该模
式提供的是“至少一次”发送的保证。
客户端
数据存储
内部表 发件箱表 发件箱
消费者和
流生产者
1) 事务写
2) 查询
发件箱
3) 写入
事件流
4) 等待
写确认
5) 删除已
写实体
事件流
事件流
事件代理
图 4-6:发件箱表变更数据捕获方案的端到端工作流
4.6.1
性能考虑
使用发件箱表会给数据存储及其请求处理应用程序带来额外的负载。对于小负载的小型数
据存储,开销可以忽略不计。但是,对于非常大型的数据存储,特别是那些有大量负载和
很多表处于捕获状态的数据存储,开销可能会非常高。应根据具体情况评估该方法的成
本,并与响应式策略(如解析变更数据捕获日志)的成本进行平衡。
4.6.2
隔离内部数据模型
发件箱表不需要与内部表成
1
∶
1
的映射关系。事实上,发件箱表的一个主要优点就是数据
存储客户端可以将内部数据模型与下游消费者隔离。领域的内部数据模型可能使用了大量
高度范式化的表,这些表对于关系型数据库是很友好的,但是极度不适用于下游消费者的
消费。即使是简单的领域也可能包含多张表,如果暴露为多个单独的事件流,就需要下游
消费者进行重新构造才能使用。由于多个下游团队将不得不重建领域模型并处理事件流中 ...