为了账号安全,请及时绑定邮箱和手机立即绑定

防止重复 AggregateCreated 事件的最佳实践

防止重复 AggregateCreated 事件的最佳实践

犯罪嫌疑人X 2022-01-06 19:43:05
我有以下(轴突)聚合:@Aggregate@NoArgsConstructorpublic class Car{  @AggregateIdentifier  private String id;  @CommandHandler  public Car(CreateCar command){    apply( new CarCreated(command.getId()) );  }  @EventSourcingHandler  public void carCreated(CarCreated event) {    this.id = event.getId();  }}我可以通过提交CreateCar具有特定 id的命令来创建汽车,从而引发CarCreated事件。太棒了。但是,如果我发送另一个CreateCar具有相同 Id 的命令,则该命令无法通过聚合验证(给定的 id 已经存在)。随后它将简单地触发一个新CarCreated事件。这是谎言。CreateCar如果汽车已经存在,确保命令失败的最佳方法是什么?当然,我可以先检查存储库,但这不会阻止竞争条件......
查看完整描述

2 回答

?
杨__羊羊

TA贡献1943条经验 获得超7个赞

但是,如果我发送另一个具有相同 Id 的 CreateCar 命令,则该命令无法由聚合验证(即给定的 id 已经存在)。随后它会简单地触发一个新的 CarCreated 事件。这是谎言。

Axon 实际上会为您处理这些。当聚合发布事件时,它不会立即发布到其他组件。它在工作单元中暂存,等待处理程序执行完成。处理程序执行后,会调用许多“准备提交”处理程序。其中一个存储聚合(使用事件溯源时无操作),另一个是事件的发布(在事务范围内)。

取决于您是否使用事件溯源,将聚合实例添加到持久存储将失败(重复键),或者创建事件的发布将失败(重复聚合标识符 + 序列号)。


查看完整回答
反对 回复 2022-01-06
?
临摹微笑

TA贡献1982条经验 获得超2个赞

如果汽车已经存在,确保 CreateCar 命令失败的最佳方法是什么?当然,我可以先检查存储库,但这不会阻止竞争条件......


没有魔法。


如果您要避免不正当写入,那么您要么需要获取数据存储上的锁,要么需要具有compare and swap语义的数据存储。


使用锁,您可以保证在读取存储中的数据和随后的写入之间不会发生冲突的更新。


lock = lock_for_id id

lock.acquire

Try:

    Option[Car] root = repository.load id

    switch root {


        case None:

            Car car = createCar ...

            repository.store car  


        case Some(car):

            // deal with the fact that the car has already been created   


    }

Finally:

    lock.release

您希望每个聚合都有一个锁,但是创建锁的条件与创建聚合的条件相同。因此,您最终可能会使用粗粒度锁之类的东西来限制对操作的访问。


通过比较和交换,您可以将争用管理推向数据存储。您不是向商店发送PUT,而是发送有条件的 PUT。


    Option[Car] root = repository.load id

    switch root {


        case None:

            Car car = createCar ...

            repository.replace car None


        case Some(car):

            // deal with the fact that the car has already been created   


    }

我们不再需要锁,因为我们正在为存储精确描述需要满足的前提条件(例如If-None-Match: *)。


事件存储通常支持比较和交换语义;将新事件“附加”到流上是通过制作一个查询来确定尾指针的预期位置,并使用特殊编码的值来标识预期创建流的情况(例如,事件存储支持ExpectedVersion.NoStream语义)。


查看完整回答
反对 回复 2022-01-06
  • 2 回答
  • 0 关注
  • 273 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号