事件溯源中是否会引发竞态条件?关于投影器执行逻辑的疑问
关于Spatie EventSourcing投影器执行顺序的核心原理
你的同事的说法是正确的——EnrollmentCreated事件的所有投影器处理逻辑,一定会在EnrollmentApproved事件的处理启动前全部完成,不会出现ProjectorA延迟导致状态被重置的情况,核心原因如下:
1. 事件的全局顺序与批次处理规则
在Spatie EventSourcing中,所有事件严格按照被记录的先后顺序处理,且同一个事件的所有投影器会作为一个"批次"来处理:
- 只有当当前事件(
EnrollmentCreated)的所有投影器(ProjectorA、ProjectorB)都执行完成(无论同步还是异步),框架才会开始处理下一个事件(EnrollmentApproved)。
2. 同步投影的直接顺序执行
如果投影器是同步模式(默认配置):
- 触发
EnrollmentCreated后,框架会依次调用ProjectorA::onEnrollmentCreated()和ProjectorB::onEnrollmentCreated(),两者都执行完毕后,才会处理ProjectorB中记录的EnrollmentApproved事件。 - 这种场景下完全不会有顺序问题,状态最终会是
approved。
3. 异步投影的队列追踪机制
如果开启了异步投影(通过队列),Spatie库通过内置的事件追踪表(默认event_projections)来保障顺序:
- 当
EnrollmentCreated事件进入队列时,库会标记该事件为"待处理",并将两个投影器的任务放入队列。 - 只有当
ProjectorA和ProjectorB的队列任务都成功执行,事件才会被标记为"已处理"。 EnrollmentApproved事件的处理流程,只会在EnrollmentCreated标记为"已处理"后才会启动,哪怕ProjectorA的队列任务有延迟,也会等待它完成。
4. 新事件的延迟处理逻辑
当ProjectorB::onEnrollmentCreated()中记录EnrollmentApproved事件时,这个新事件会被添加到事件流,但它的投影处理不会立即触发——框架会确保当前事件的所有投影工作完成后,才会调度后续事件的处理。
内容的提问来源于stack exchange,提问作者jmadsen
相关产品推荐
相关产品推荐

