gpt4 book ai didi

c# - CQRS与提交数据时的冲突

转载 作者:太空宇宙 更新时间:2023-11-03 21:22:49 25 4
gpt4 key购买 nike

因此,我最近开始阅读有关CQRS /事件源的文章,这似乎很有趣。但是,我只是无法解决这种情况似乎很容易解决的问题。

说我们有这个控制器动作:

public ActionResult UpdateCustomerName(int customerId, string newName) {
var aggregateRoot = _customerQueryService.GetCustomer(customerId);
_bus.Send(new UpdateCustomerNameCommand{Customer = aggregateRoot, NewName = newName});

return View();
}


在某些示例中,我已经看到了这段代码。在命令处理程序中检测到冲突很简单,因此尝试进行一些自动合并。我没有看到,也感到困惑的是,当&发生冲突且无法解决时,该控制器如何优雅地通知用户,导致UpdateCustomerNameCommand被拒绝。

我们是否不需要以某种方式通知用户?

最佳答案

检测冲突的典型解决方案是在您提交的命令中使用事件流的“预期版本”。

在客户端表单中,查询要显示的信息时,请确保您还获得了聚合根目录或事件流的当前版本。然后,在提交命令时将此版本设置为预期版本。

然后,如果预期版本与当前事件流版本不匹配,则命令处理逻辑可以检测到冲突。根据命令和所需的行为,可以尝试以下几种操作:


如果新命令不与任何内容冲突(例如添加订单行),则只需执行即可。
您可以尝试使用自定义逻辑将其效果与自预期版本以来所做的更改合并。
您可以发出特定于冲突的事件,该事件可使用户解决该事件。
您可以使命令失败。


这里没有一般的食谱。这实际上取决于冲突在语义上意味着什么以及用户希望如何解决此类冲突。如果冲突的某些部分可以自动解决,请这样做,其余部分由用户解决。

请注意,此类情况并非错误。如果您希望允许用户同时从事某项工作,并且您和您的用户都知道您在一个最终一致的世界中工作,那么他们就是预期的。

问题编辑后更新:
您提供的新示例有些人为,因为它没有揭示此更改的意图,也没有揭示该更改与任何业务规则或流程的相关性,但是我将通过适应它来说明意图与之非常相关的上下文来进行操作。一点点。让我们假设该软件在负责处理legal name changes的组织中使用。

因此,我们可能有以下意图来揭示可用于办事员处理的命令,这些命令用于处理由于法院命令,婚姻或离婚而导致的授予的姓名更改请求:

ChangeLegalNameToMarriedName(... command specific info ...);
ChangeLegalNameToDivorcedName(... command specific info ...);
ChangeLegalNameToNaturalizedName(... command specific info ...);
ChangeLegalNameToNewGenderName(... command specific info ...);
... others


这些命令中的每一个在处理命令时可能会调用一些不同的业务逻辑,例如确保收到 ChangeLegalNameToDivorcedName命令时该人的状态为“已婚”。

另外,在进行更改之后,很可能还会触发需要进行的其他过程。即进行更改后生成的 LegalNameChangedToNaturalizedName事件可能会启动业务流程,该业务流程会将电子邮件发送给相关的移民官。 LegalNameChangedToDivorcedName事件可能会启动一个过程,该过程将所有潜在的新客户通知给所有当地的约会机构;-)。

因此,以您的示例为例,假设业务员1刚提交了一个预期总版本为5的 ChangeLegalNameToNewGenderName命令,我们考虑了两种不同的潜在冲突情况:


职员2在同一时间处理了相同的请求并发送了相同的命令。
因为总体上的命令通常是事务处理的,所以假设首先处理了文员2的命令,成功后将其版本提高到6。当文员1的命令得到处理时,我们检测到潜在的冲突。通过检查从版本5开始生成的事件,我们可以看到 LegalNameChangedToNewGenderName存在,并且其内容与秘书1提交的命令相匹配。因此,根据我们的业务规则,我们执行以下操作:(1)跳过执行秘书1的request(2)在 RegisterDuplicateNameChangeRequestProcessingAttempt集合上执行 LegalNameChangeProcess命令,这反过来又可能生成一个事件,供主管检查内部过程出了什么问题。
同时,处理了具有不同内容的合法名称更改命令。对于组织而言,这将代表一种特殊且可能令人担忧的情况。它应导致采取行动来解决(a)潜在的内部流程中断(b)潜在的欺诈性合法名称更改尝试。可能要做的是(1)使用补偿命令还原由第一个命令引起的人员姓名,将其标记为需要解析。 (2)在 ResolvePotentiallyFraudulentLegalNameChange聚合上执行 LegalNameChangeProcess命令。


如果您提供的示例可能是这样,则没有与之相关的有价值的业务逻辑。客户名称,请勿在应用程序的那部分使用CQRS,而只需执行CRUD。仅在可增加实际价值的地方使用它。参见例如此处的讨论 CQRS and CRUD screens

还请注意,UI /客户端可能会接收生成的事件,以便可以向用户通知在编辑时发生名称更改的事实。显然,这只会减少比赛的可能性,而不会阻止比赛。如果在您的示例中发生了比赛,则意味着不应执行“名称更改”命令,则可以生成“名称更改被拒绝”事件,该事件可以传递回给用户(例如,使用命令&事件)。

关于c# - CQRS与提交数据时的冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29532192/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com