3

聚合根源在那里可以控制状态变化 - 当前允许的和不允许的。如果允许状态转换,继续。如果不是,你会抛出一个异常,解释为什么它不被允许。Aggregate-Root:State更改或失败,异常或...?

但什么是如果国有变化不会发生,因为它是已经在请求国

例如,如果您的聚合根目录上有Approve方法,并且在调用该方法时状态已被批准?

  • 如果一个抛出异常一拉 “XYZ已经批准”?
  • 还是应该是默默忽略
  • 还是应该状态变化再次“发信号”(事件采购,下一段)?

在我的情况下,我使用事件源,所以如果发生状态改变,事件正在发射。在我的事件流中发生没有真正状态变化的事件并不会对我感觉“干净”,因为我希望确信这些事件实际上是由于改变状态的行为而产生的。

有没有经验法则?

编辑:
在所描述的情况下批准认可的元素不会真的伤害。所以倾向于这种方式(谢谢@Eben Roux,@ guillaume31)。

但是,让我们多一点香料添加到它(这个问题背后的实际问题):

假设:

  • 消息总线
  • 异步命令/事件处理
  • 一个进程管理器

如果进程管理器(aka saga)发出命令(异步)并想知道命令是否成功会怎么样?我认为如果进程管理器不必关心关于这个实现细节,那么减少精神负载/错误来源

我看到处理3种方式是:

  • “命令ID为ABC成功/失败”总线
    流程管理器等待发送的消息,而不是事件的信息
  • 使命令执行同步
    如果流程管理器遭遇也不例外,一切都很好,继续前行
  • 引入新的事件此事件ApprovalDeclined { WasAlreadyApproved = true }
    额外的过程管理器等待 - 磁偏角是集合历史记录,也许是有利的,也许根本不需要的部分...

我知道:“它取决于“
但你能想到任何其他(更优雅/更容易/不同)的解决方案吗?处理这个问题最喜欢的“过程管理器兼容”方式是什么?

回答

2

我不认为这会有一个经验法则。

消息idempotence当然是一件好事,所以简单地忽略消息/状态变化是或许是要走的路。

我不会再发信号,因为没有效果。

1

我想说这取决于你的域名。如果你想警告用户他们正在批准已经批准的东西,那么总会有一些反馈。它可能是一个例外as in Deactivate() here或由应用程序服务/命令处理程序中继的返回值(注意这可能不是100%CQRS兼容)。

如果批准已经完成的事实对域任务来说并不重要,那么您可以忽略该操作或再次执行该操作。

从用户的角度来看,你将最有可能不允许反正重新核准的东西,那么,这种情况将是边际的情况下:并发认证2个用户,脚本,做“强力”审批等

+0

是的,+1取决于您的域名(或者,或者常识)。 – 2014-09-30 12:18:28

0

看来 - 对我来说 - 你很困惑应用程序和基础设施级的问题。

应用程序级别涉及预期的域特定行为。什么是两次批准的商业理由?为什么甚至会首先发生?也许这只是一个UI级别的并发事件,但是,为什么多个用户在同一时间批准同一件事?也许他们尚未解决的业务层面存在问题。理解为什么第一是必不可少的。解决方案通常不在软件本身中。

基础架构级别涉及诸如保证消息传递(例如至少一次或恰好一次)的事情。当基础设施无法兑现承诺时,这会如何影响业务(如果有的话)?它如何影响你的过程?无论如何,你的过程是什么?再次,从领域特定的角度来看,推断这些事情是非常重要的。在一天结束时,您可以采取风险或运营成本减轻措施。

在这种特殊情况下,问自己为什么以及如何在启动批准命令之前将流程放到了哪里(批准过程有点奇怪,通常由人工完成)。它怎么没有遵守以前的批准(记住,这个曾经聚集的东西已经被批准了)?你可以引入一个超时(作为一个消息给它的(过程)未来的自我),但是在这种情况下做这件事似乎有点奇怪(我几乎不知道该说什么)。

不要采取这种错误的方式,但我认为你需要深入挖掘领域特定的一面或共享更多的细节。

+0

我来回读了你的回答,但我认为它不符合我试图找出的观点 - 但仍然非常感激! (发展中的)问题不是关于消息传递 - 更重要的是:过程管理器如何知道它的命令成功 - 以一般方式?除了特定的情况 - 这只是一个(也许是坏的)例子 - 我仍然试图在我已经完成时做了些什么,我需要实现一个进程管理器(没有ESB)... – 2014-11-04 22:59:07

+0

...这会影响聚合体处理这种无状态变化 - 例外或无事件发射 - 传递的“规则”。要么是:没有aggregate-state-change => exception =>在其中带有command-id的总线上的CommandFailed系统事件。 “失败”,虽然总量处于合适的状态?似乎错了。或者:在总线上没有发出event-message => CommandSucceeded系统事件,没有聚合状态改变=>命令“通过”。这对我来说最有意义,尽管现在进程管理器监听系统事件,而不是“正常”事件......我只是在这个问题上寻找一些指导。 – 2014-11-04 23:16:31

相关问题