在CQRS系统中,我应该如何向用户显示他们的请求已被收到?

时间:2011-11-05 12:33:30

标签: nservicebus msmq cqrs

我正在尝试将我们的大球体系结构中的一些部分去耦,并确定了几个明显可以选择使用CQRS来提供更具弹性和可扩展性的解决方案的边界。

典型示例:当客户下订单时,我们在订单提交付款时被阻止他们的线程,由销售系统批准等等。

这可以全部异步处理 - 允许我们在付款处理系统不可用时接受和排队订单等等 - 但我不确定如何管理客户的UI数据。

换句话说 - 他们下订单。他们的订单排在队列中。如果他们在五秒钟后重新登录他们的帐户并点击“审核订单” - 会发生什么?

  • 如果我从中央仓库(或从基于该仓库更新的缓存)中提取它,那么用户将看不到他们的订单,并且可能会尝试重新放置它 - 或者给我们打电话并恐慌。
  • 如果我从本地数据库中绘制它,那么我有维护另一个订单数据库的开销 - 这需要在负载均衡的环境中同步,并且似乎破坏了很多CQRS的优势。

我想在很多地方这样做 - 而且并非所有这些行动都像确认订单一样重要;在某些情况下,它就像客户更改电话号码一样简单 - 所以他们并不是所有我只能说“非常感谢,我们会向您发送确认电子邮件”的情况 - 因为发送确认电子邮件每次修改记录的邮件都让我觉得有些过分。

我应该考虑哪些模式或解决方案来帮助解决这个问题?

4 个答案:

答案 0 :(得分:5)

  • 值得考虑的是“用户”收件箱:用户可以在应用中查看“进行中”命令的位置。当他已经移动到另一个屏幕上时,您也可以将通知“推送”回用户的UI,但仍然存在于您的应用中。当用户重新登录时,这也可能是一个选项。
  • 另一种选择可能是伪造同步体验,即等待并在后台进行轮询,所有事情都是异步发生的。当然,这也可能涉及包括超时,但我认为这些也包含在今天的同步处理中。
  • 除此之外,您可能希望通知并征求最终用户对他们如何体验您的应用及其行为的反馈。
  • 无论有人告诉你什么,如果你想优雅地处理这个问题,你需要付出一些努力。

答案 1 :(得分:3)

最好的办法就是撒谎!

用户应该不知道他们的交易实际上有点像薛定谔的猫,无论是死还是活。从他们的角度来看,交易是成功的,因为你只是向他们表明它是成功的,并将工作排队等离线处理。

由于绝大多数交易都是成功的,因此您可以处理那些没有适当补偿机制的交易。

答案 2 :(得分:2)

不重要的案例,例如修改某些记录:

  1. 将用户发送到确认页面,告诉他“谢谢,您的输入正在处理中。”接下来您要做什么?还有几个链接。
  2. 如果您必须将用户发送回已编辑的记录或其列表,则在非分布式系统中,我们可能会谈论毫秒,直到读取存储更新为止。只要将用户重定向到新页面需要更长的时间,从用户的POV开始一切都很好。
  3. 如果在某些情况下用户实际上没有“立即”看到他的更新,他可能会致电用户支持。他们告诉他打F5。什么?它现在在那里?大!猜猜他下次打电话之前他做了什么。
  4. 离线订单处理等重大案例:

    您的域中可能存在已接收订单待处理订单的隐含概念。如果您明确说明此概念,则可以向用户提供准确的信息。

    “非常感谢!我们已收到您的订单,我们会在发货后随时更新。[点击此处]查看您的挂单清单......”

答案 3 :(得分:1)

我认为最简单的事情,什么都不做,往往足够好。如果用户更改了电话号码,并且系统在1-2s内处理此命令,则用户很可能无法在此操作之间查看旧数据。

如果不满意,并且您的用户必须完全知道他的请求已满足,您的UI可以订阅域事件。成功执行命令后,您的UI会收到通知并可以通知用户。您可以通过各种方式在UI中执行此操作。您可以直接阻止,直到成功通知到达。或者您可以说“我们已收到您的请求”,一旦您收到确认,请在角落的某个位置显示“您的请求已完成”的通知窗口。