Lagom框架如何识别事件与对应实体的关联?
先看你提到的这段关于事件溯源的核心描述:
实体不会被持久化在任何地方——这正是事件溯源的核心,你只需存储事件,这种实现方式非常简单,易于分布式部署,且仅需追加操作,性能极高。当需要加载实体时,会加载该实体对应的所有事件,然后通过你声明的事件处理器处理每个事件,生成实体的当前状态。
针对你的问题:Lagom是通过唯一的「实体标识符(Entity ID)」来实现事件与实体的绑定的,下面结合你的用户CRUD场景详细解释:
1. 每个实体实例都有专属的唯一ID
在Lagom中,你创建的UserEntity是一个实体模板,而每个具体的用户(比如Alice、Bob)都是这个模板的实例,每个实例都需要一个唯一的ID来标识——比如你可以用用户名、用户UUID作为ID。
当你发起创建Alice的请求时,你需要在命令中指定这个ID(比如"alice");Lagom会根据这个ID找到对应的UserEntity实例(如果不存在就新建),然后处理你的创建命令。
2. 事件存储时自动关联实体ID
当UserEntity处理命令生成事件(比如UserCreated、UserUpdated)时,Lagom的持久化框架会自动把当前实体的ID和事件绑定在一起,存储到事件日志中。你不需要手动在事件里添加ID字段,这个关联是框架自动完成的。
就像你的例子:
- 创建Alice时,生成的
UserCreated事件会和ID"alice"关联存储 - 更新Alice时,生成的
UserUpdated事件同样和ID"alice"关联存储 - 创建Bob时,生成的
UserCreated事件则和ID"bob"关联存储
3. 加载实体时按ID过滤事件
当需要重建Alice的实体状态时,Lagom会根据她的实体ID"alice",从事件日志中查询所有关联了这个ID的事件,然后按事件发生的顺序逐个重放,通过你定义的事件处理器(比如onEvent方法)来生成Alice的当前状态。同理,加载Bob的状态时,只会查询关联ID"bob"的事件,也就是那一个创建事件。
补充:Lagom代码层面的体现
在Lagom中,你通过entityRefFor方法获取实体引用时,必须指定实体ID:
EntityRef<UserCommand> aliceRef = entityRefFor(UserEntity.class, "alice");
当你通过这个引用发送命令时,Lagom就知道要把后续生成的事件和"alice"这个ID绑定。而在UserEntity的persist方法中,框架会自动带上当前实体的ID,无需你额外处理。
内容的提问来源于stack exchange,提问作者piyushGoyal

