Axon Framework导入Excel实体/实现批量插入的最优方案
Axon Framework 批量导入Excel/批量插入实体最优方案解析
三种方案优劣及疑问解答
方案一:将Excel字节数组作为入参构造Command,在聚合内部解析文件并逐行生成事件
- 优点:文件解析、校验、事件生成逻辑全收敛在聚合内部,天然保证整批处理的原子性,不会出现外部解析错误导致的无效请求
- 缺点:违反单一职责原则,聚合承担了非业务属性的文件解析工作;Excel文件过大时会导致
Commandpayload超出消息中间件的大小限制,同时解析耗时过长会拉长聚合锁的持有时间,大幅降低整体吞吐量 - 适用场景:仅适合文件行数极少(10行以内)的极特殊场景,生产环境绝大多数情况不推荐
方案二:直接发送包含实体列表的批量Event,聚合更新逻辑如下
聚合更新步骤:首先构造携带已解析实体列表的
批量实体创建Command,聚合接收Command后完成全局校验(比如批量条数上限校验、数据去重、关联资源存在性校验等),校验通过后发送单条XX实体批量创建Event,再通过@EventSourcingHandler监听该事件,循环遍历实体列表完成聚合内部状态的更新即可。
- 优点:大幅减少Command、Event的投递数量,降低消息中间件压力,吞吐量高于逐行发送的方案
- 缺点:事件粒度过大,后续事件溯源、快照生成、事件重播的灵活性大幅下降;单批条数过多时同样会出现payload过大、聚合锁持有时间过长的问题;后续如果需要针对单条实体的创建做定制化扩展逻辑,处理复杂度会明显提升
- 适用场景:仅适合实体之间强绑定、必须同时生效/失败,且单批条数严格控制在100条以内的场景
方案三:聚合外部完成Excel解析,逐行生成单独Command
- 优点:完全符合Axon以及DDD的设计规范,聚合职责纯粹,仅处理核心业务逻辑;事件粒度小,溯源、重播、业务扩展都非常灵活;单条Command执行速度快,聚合锁持有时间短,吞吐量可控
- 缺点:数据量极大时会产生大量Command、Event,对消息中间件的吞吐量有一定要求;如果需要保证整批导入的原子性,需要额外引入Saga编排或者补偿机制
- 适用场景:绝大多数通用场景的首选方案,生产环境优先推荐
落地最优建议
- 常规场景优先选择方案三,将Excel解析逻辑放在应用服务层处理,解析阶段提前完成格式校验,过滤无效数据后再发送Command,减少无效请求对聚合的压力;如果需要保证整批导入的原子性,可搭配Saga做流程编排:先发送
启动批量导入Command生成导入任务聚合,Saga监听任务启动事件后逐行投递单实体创建Command,全部执行成功后标记导入任务完成,任意一条执行失败则触发补偿逻辑,回滚已生成的实体并标记任务失败 - 仅在对吞吐量要求极高、且无单条实体事件溯源需求时,选择优化后的方案二,严格限制单批条数不超过100条,同时在批量Event中保留每条实体的唯一标识,方便后续问题排查
内容的提问来源于stack exchange,提问作者Alexandre
相关产品推荐
相关产品推荐

