.net core CQRS saga/process manager是同步执行一组相关命令的最佳方法吗?

.net core CQRS saga/process manager是同步执行一组相关命令的最佳方法吗?,.net-core,cqrs,masstransit,saga,.net Core,Cqrs,Masstransit,Saga,我有一个CQRS.NET核心服务,目前每个命令都有一个端点。有时,一组命令组成系统中的单个操作(例如,创建评估),一旦前一个命令将数据提交给数据库,就必须同步执行3个左右的命令(这是因为传统数据库设计) 目前,这是由客户机处理的,其中每个命令在其上一个依赖命令完成后激发(使用承诺) 值得注意的是,这些命令有时也是单独执行的,如果将它们合并到一个命令中,那么最终将非常庞大,并且很难进行测试 我想做的是创建一个端点来管理像我们的create assessment one这样的操作,它必须一个接一个地

我有一个CQRS.NET核心服务,目前每个命令都有一个端点。有时,一组命令组成系统中的单个操作(例如,创建评估),一旦前一个命令将数据提交给数据库,就必须同步执行3个左右的命令(这是因为传统数据库设计)

目前,这是由客户机处理的,其中每个命令在其上一个依赖命令完成后激发(使用承诺)

值得注意的是,这些命令有时也是单独执行的,如果将它们合并到一个命令中,那么最终将非常庞大,并且很难进行测试

我想做的是创建一个端点来管理像我们的create assessment one这样的操作,它必须一个接一个地执行以下命令:

  • 用户创建
  • 创建评估
  • 评估注册客户
  • 我一直在使用MassTransit saga/状态机/流程管理器,但我对它的研究越多(我的理解也越深入),我就越觉得它似乎有些过火,不是正确的方法(因为这些都是命令而不是事件,都在一个有界的上下文中)


    流程管理器看起来合适吗?如果合适的话,MassTransit状态机实现是正确的选择,还是应该查看其他来源?或者我应该只创建一个端点,一次触发一个命令(即在ASP控制器中有此同步代码)?

    只是澄清一下,
    UserCreated
    不是命令,而是事件

    这里有三种选择:

    • 而是建立一个反应性系统。因此,在
      CreateUser
      (顺便说一句,这里的语言不是很好,因为您从未创建用户,他们在您的系统中注册)之后,您会发出
      UserCreated
      ,这会导致发送命令
      CreateAssessment
      的反应,依此类推
    • 将MT saga用作流程管理器。如果您需要确保您的复杂工作流以您期望的方式完成(或失败),状态机非常适合
    • 使用MT courier功能实现分布式事务。您将有一系列活动、操作和补偿操作(反转)
    我会亲自分析我的问题,找出我需要做的最低限度是什么,然后才能返回给用户并说“没问题”。其余的可以在幕后异步完成。它更多的是领域分析,而不是技术分析

    更新日期:2019年12月4日,回复其中一条评论:

    同样,目前使用的术语也存在问题。许多消息传递库,如MassTransit、Rebus或NServiceBus,都使用saga这个词来表示流程管理器

    使用原始术语,流程经理处理可能存在偏差和并行的整个流程。另一方面,Sagas实现了单流流程。当故事中的任何一步失败时,之前发生的一切都会通过补偿动作恢复。传奇没有编排,因为每一步都是独立的,当一步完成时,下一步就会执行。saga总是无状态的,如果需要为下一步包含一些额外的信息,saga活动需要将其放入有效负载

    根据定义,流程管理器是编排器。它从不自己做这项工作,而是指示其他组件做这项工作。然后,通过倾听事件,流程经理决定流程应该如何流动。
    process manager可以启动补偿操作,但它本身不执行该操作,而是指示另一个组件执行该操作。为了保持流程的当前状态,流程管理器是有状态的。

    因为所有命令都是由同一个聚合处理的,所以解决方案是创建第四个组合命令,以通用语言命名,其中包含3个命令。在内部,聚合只调用3个命令方法,因此没有代码重复

    作为最简单的解决方案,它还明确表示,在这个特定的用例中,这些命令在单个事务中按顺序执行:它们要么成功,要么失败


    另外,正如@AlexeyZimarev指出的,这些不是命令,而是事件

    所有命令都由同一个聚合处理?如果您没有使用DDD,那么“在相同的事务边界中”@ConstantinGalbenu是的,这是正确的(有点)。每个命令实际上都在它自己的事务中执行。为什么要将用户创建为事件而不是命令(或者不是两者)?我的理解是,因为用户记录是在数据库中创建的(在本例中为匿名记录),所以它是一个命令?我想这就是我的理解开始有点动摇的地方。不幸的是,最基本的要求是三个“命令”全部完成,并且没有一个可以异步启动,因为每个命令都需要在数据库中提交前一个命令中的实体。我正在努力解决的是如何用一部MT传奇真正做到这一点,但我认为我可以解决它。我正在努力解决的是如何“开始”我的传奇并构建它。我是在监听用户创建的事件(在用户创建后触发)还是有更好的方法,比如发送一个新命令(例如CreateAssessmentAndUser),然后从那里开始执行?命令和事件之间的区别非常清楚。命令表示做某事的意图,事件表示某事已经发生。命令的命令式风格意味着发送者告诉接收者做某事。但它还没有完成。命令处理可能会失败,在这种情况下不会产生任何事件。这种区别是很重要的