CQRS 事件溯源:验证用户名唯一性

2024-02-28

我们以一个简单的“账户注册”为例,流程如下:

  • 用户访问网站
  • 点击“注册”按钮并填写表格,点击“保存”按钮
  • MVC 控制器:通过读取 ReadModel 来验证用户名的唯一性
  • RegisterCommand:再次验证用户名唯一性(这是问题)

当然,我们可以通过读取MVC控制器中的ReadModel来验证UserName的唯一性,以提高性能和用户体验。然而,我们仍然需要在RegisterCommand中再次验证唯一性,显然,我们不应该在命令中访问 ReadModel。

如果我们不使用事件溯源,我们可以查询域模型,所以这不是问题。但是如果我们使用事件溯源,我们将无法查询域模型,因此我们如何验证 RegisterCommand 中的用户名唯一性?

Notice:User 类有一个 Id 属性,而 UserName 不是 User 类的关键属性。使用事件溯源时,我们只能通过Id获取领域对象。

BTW:需求中,如果输入的用户名已被占用,网站应向访问者显示错误消息“抱歉,用户名XXX不可用”。不可接受向访问者显示“我们正在创建您的帐户,请稍候,我们稍后会通过电子邮件将注册结果发送给您”的消息。

有任何想法吗?非常感谢!

[UPDATE]

一个更复杂的例子:

要求:

下订单时,系统会检查客户的订单历史,如果他是有价值的客户(如果客户去年每月至少下了10个订单,他就是有价值的),我们对该订单给予10%的折扣。

执行:

我们创建PlaceOrderCommand,在命令中,我们需要查询订购历史记录,看看该客户是否有价值。但我们怎样才能做到这一点呢?我们不应该在命令中访问 ReadModel!饰演 米凯尔said https://stackoverflow.com/a/9496198/290617,我们可以在账户注册的例子中使用补偿命令,但是如果我们在这个排序的例子中也使用它,那就太复杂了,而且代码可能太难维护了。


如果您在发送命令之前使用读取模型验证用户名,那么我们正在讨论一个几百毫秒的竞争条件窗口,其中可能会发生真正的竞争条件,而在我的系统中不会处理这种情况。与处理它的成本相比,这种情况发生的可能性太小了。

但是,如果您觉得出于某种原因必须处理它,或者您只是想知道如何掌握这种情况,那么这里有一种方法:

使用事件源时,不应从命令处理程序或域访问读取模型。但是,您可以做的是使用域服务来侦听 UserRegistered 事件,在该事件中您再次访问读取模型并检查用户名是否仍然不重复。当然,您需要在此处使用 UserGuid,并且您的读取模型可能已使用您刚刚创建的用户进行了更新。如果发现重复,您有机会发送补偿命令,例如更改用户名并通知用户该用户名已被占用。

这是解决问题的一种方法。

正如您可能看到的,不可能以同步请求-响应方式执行此操作。为了解决这个问题,每当我们想要将某些内容推送到客户端时(也就是说,如果它们仍然处于连接状态),我们就会使用 SignalR 来更新 UI。我们所做的是让 Web 客户端订阅包含对客户端立即查看有用的信息的事件。

Update

对于更复杂的情况:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CQRS 事件溯源:验证用户名唯一性 的相关文章

  • R - 根据两列识别并删除重复行

    我有一些数据看起来像这样 Course ID Text ID 33 17 33 17 58 17 5 22 8 22 42 25 42 25 17 26 17 26 35 39 51 39 由于没有编程背景 我发现很难清楚地表达我的问题 但
  • SQL聚合函数选择唯一值

    我有一个包含两列的行集 technical id and natural id 行集实际上是复杂查询的结果 假设列值之间的映射是双射的 即对于具有相同值的两行 technical id the natural ids 也相同 对于不同的te
  • BL 服务:异常还是方法结果?

    最好的方法是什么 为什么 V1 try var service IoC Resolve
  • rand() 在 C 语言中有多独特?

    我在用rand 对于需要唯一值的 6 位字段 我做对了吗 几率有多大 rand 可以在连续或频繁的通话中给我类似的值吗 当我使用 rand 时 它是独一无二的 但是 当我打电话时返回相同的号码srand time NULL or srand
  • DDD和应用层

    我在DDD中添加 Stateful Stateless WebService等是应用层 应用服务 吗 从下面的链接来看 这似乎是正确的 第二个问题 我创建了一个存储库类 所有涉及存储库的方法调用都应该包装在应用程序服务中吗 或者我可以直接在
  • 如何查找 MASSIVE 数组中哪些项出现多次?

    这是一个非常简单的问题 哪些项目在列表中出现多次 array mike mike mike john john peter clark 正确答案是 mike john 看来我们只能这样做 array select e ary count e
  • 实现领域驱动设计的函数式方法

    我在使用 C 编写领域驱动应用程序方面拥有丰富的经验 我编写的应用程序越多 我就越发现我想要采用一种不太适合标准 C OO 技术的方法 我想编写尽可能多的纯函数 因为它们真的很容易测试 我想以更具声明性的方式编写我的业务逻辑 所以我一直在研
  • DDD 领域模型复杂验证

    我正在努力使用域驱动设计原则重写我的 ASP NET MVC 应用程序 我正在尝试验证我的用户实体 到目前为止 我能够验证基本规则 例如用户名和密码是非空 空白字符串 然而规则之一是 我需要确保用户名是唯一的 但是 我需要访问数据库才能执行
  • 有界上下文、子域和通用语言

    a 对于包含两个或多个子域的 BC 存在概念重叠的可能性 甚至更糟糕的是 相同的概念 由其中几个子域使用 可能会被每个子域以不同的方式解释 理解 无论如何 如果 BC 确实包含许多子域 它是否应该提供几种通用语言 每个子域一种 或者所有子域
  • 定义具有多种消息类型的消息传递域

    到目前为止 我见过的大多数 F 消息传递示例都使用 2 4 种消息类型 并且能够利用模式匹配将每条消息定向到其正确的处理函数 对于我的应用程序 由于处理和所需参数的不同性质 我需要数百种独特的消息类型 到目前为止 每个消息类型都是其自己的记
  • 按组添加ID列[重复]

    这个问题在这里已经有答案了 我想根据两列纬度和经度在 R 中创建一个唯一 ID 以便重复的位置具有相同的集群 ID 例如 LAT LONG Cluster ID 13 5330 15 4180 1 13 5330 15 4180 1 13
  • 如何从数组C++中获取唯一的字符串

    我知道我的问题对某些人来说可能很愚蠢 但我整天用谷歌搜索并尝试制定自己的解决方案 但我失败了 请帮助 我需要从简单的字符串数组中打印所有唯一的字符串 example 输入 嗨 我的 名字 嗨 土豆 文本 名字 嗨 输出 我的 土豆 文本 我
  • 如何使用 codeigniter 生成 5 位字母数字唯一 ID?

    我有一个项目 需要为用户生成唯一的 5 位数字母数字 ID 我怎样才能使用 codeigniter 实现这一点 thanks 字符串助手中有一个名为 random string 的函数 this gt load gt helper stri
  • 有丰富的领域模型示例吗? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个简单的示例来说明使用富域模型的好处 理想情况下 我想要一个之前和之后的代码列表 应该尽可能
  • 在 DDD 中,表示层可以同时使用 Repository 和 Service 类吗?

    如果表示层只应该使用服务 那么服务类必须公开存储库已实现的相同方法 以使它们可供表示层使用 这似乎是错误的 有人可以帮我澄清一下吗 我敢打赌 这似乎是错误的 因为您实际上并不需要这种抽象级别 应用服务有facades http en wik
  • 迁移范围的独特性

    我一直在尝试找到一种方法来实现这一目标 但我找不到任何尝试 即使如此 我想也许我的方法是完全错误的 也就是说 我应该做什么移民如果我希望两个字段的组合是唯一的 请注意 我不希望它们成为索引 而只是数据库字段 例如 对于下面的迁移 我可以单独
  • 具有持久性无知对象的持久性和领域事件

    我一直在研究领域驱动设计领域事件 http www udidahan com 2009 06 14 domain events salvation 我真的很喜欢这些事件提供的关注点分离 我遇到了保留域对象和引发域事件的顺序问题 我想在域对象
  • 如何在 CQRS 中处理基于集合的一致性验证?

    我有一个相当简单的域模型 涉及一系列Facility聚合根 鉴于我使用 CQRS 和事件总线来处理从域引发的事件 您如何处理集合的验证 例如 假设我有以下需求 Facility必须有一个唯一的名称 由于我在查询端使用最终一致的数据库 因此在
  • 领域模型可以知道存储库吗?

    可能对于某些域逻辑实现实体需要访问存储库以更新 删除自身或任何相关实体 这听起来对吗 不 不是 至少对于标有 的问题 领域驱动设计 标签 当然 Active Record 模式有权在某些系统中生存 并且有些人发现强耦合很有用 但在 DDD
  • postgresql 登录到另一个表时发生冲突

    我正在使用 PostgreSQL 9 5 并尝试使用批量插入每天插入数百万行 INSERT INTO tours as cst adults country id price VALUES 3 129 80 2 119 120 on con

随机推荐

  • 使用 Vagrant 管理开发和生产环境?

    人们如何使用 vagrant 最好来自同一个 vagrantfile 处理开发 生产环境的简单自动化 使用 puppet 我试图解决的用例 如果没有创建的话 我很乐意用 vagrant 来启动生产机器 如果在我的开发环境的 puppet 文
  • 直到阈值为止的数字列表的总和

    我有一个整数列表 我想要对其进行求和 直到满足阈值 然后能够访问达到阈值的索引 就像是 summing lt function i sum sum list i index i while sum lt thresholdValue sum
  • HTML5 视频 - 设置 video.currentTime 会破坏播放器

    我正在尝试与 Chrome 中的第三方 html5 视频播放器进行交互 我能够因此获得对它的有效引用 document getElementsByTagName video 1 以及readyState是 4 所以一切都很好 我可以成功 并
  • Gradle - 排除配置的依赖关系,但不排除继承配置的依赖关系

    使用 Gradle 1 0 里程碑 8 我的项目使用 slf4j Logback 进行日志记录 因此我想防止 log4j 上的任何传递依赖项污染我的类路径 因此 我添加了全局排除 如下所示 configurations all exclud
  • 定义自定义颜色变量

    我想在我的代码中全局更改一些按钮颜色 我似乎无法找到一种定义颜色变量然后为该变量分配颜色值的方法 我试过这个 颜色 SelectedColor new Color f1 setBackgroundColor Color rgb 0 0 10
  • C# 以编程方式执行 TNSPing

    是否可以以编程方式在 Oracle 数据库上执行 TNSPing 我知道我可能可以调用 TNSPing 程序并解析生成的任何输出 但我正在寻找一种更强大的方法来处理数据库 TNS Ping 看过了平级 http msdn microsoft
  • 为什么 String 的 format(Object...args) 定义为静态方法?

    我想知道为什么Java5 及以上版本提供了使用 String 类中的静态方法的 printf 样式格式化程序 如下所示 public static String format String format Object args 代替 pub
  • 如何在 ASP.Net 应用程序上使用 salting+hashing?

    我正在从头开始构建一个项目 并且我想以正确的方式做事 我在网上读过有关哈希的内容 这基本上就是将密码转换为 64 个字母的繁文缛节 对吗 腌制怎么样 我的问题是 如何使用 C 对字符串进行哈希处理 MSSQL 中的字段声明类型是什么 nva
  • MVC HTML5 电子邮件标签

    我有一个模型 Required ErrorMessage Email required DataType DataType EmailAddress ErrorMessage Please enter valid email address
  • PowerPoint VBA 中的睡眠/等待计时器不是 CPU 密集型的

    我目前正在制作一个 PowerPoint 演示文稿 该演示文稿在计算机上用作某种信息亭或信息屏幕 它从磁盘上的文本文件中读取文本 该文本文件中的文本显示在 PowerPoint 的文本框中 并且每 5 秒刷新一次 这样我们就可以编辑 Pow
  • 从查询引用子表单

    在 MS Access 2010 中 我有一个查询 它在条件中引用了以下内容 Forms frm Add Item Subform ActiveControl Caption 这使我可以在查询中使用按钮的 标题 文本 以下代码位于 Butt
  • 将触摸和手势转发到 UIScrollview 的视图

    我在转发手势和触摸时遇到一些问题 我玩了很多次 但我无法让它按照我想要的方式工作 基本上我想用 2 个手指控制双屏幕上的滚动视图 并将其他所有内容转发到重叠滚动视图后面的 ipad 视图 为了能够控制双屏上的滚动视图 我进行了子类化UISc
  • 如何将包含 7 位毫秒数的日期字符串转换为 Python 中的日期

    当毫秒有 6 位数字时 f 有效 但如果超过 6 位数字 则会抛出错误 我有一个临时解决方案 将第 7 位硬编码为 0 但是有更好的方法吗 目前以下作品 print datetime datetime strptime 2014 11 19
  • ActiveAdmin - 如何在自定义操作中呈现默认模板

    我们在 Rails3 应用程序中使用 ActiveAdmin 作为默认模型 现在我们需要覆盖显示操作 OrderProcess 模型是瞬态 无表 模型 这意味着所有字段都是从其他数据聚合而来的 我们使用一个内部模块 它提供了必要的方法来模拟
  • 如何以缓存友好的方式访问灵活数组的数组?

    I have records具有灵活的阵列成员 typedef struct record unsigned foo signed bar double number record 我有多个records与相同数量的numbers这样我就可
  • SignalR:加载集线器时出错

    Signalr 不加载我的集线器 SignalR Error loading hubs Ensure your hubs reference is correct e g 我正在打电话app MapSignalR in startup co
  • 未捕获的ReferenceError:未定义FileTransfer(使用cordova 2.7.0)

    我想使用FileTransfer从网络服务器下载文件 代码如下 function downloadFile url var fileTransfer new FileTransfer var uri encodeURI url var fi
  • 异步填充DataTable?

    我在 NET Core 2 0 应用程序中有以下功能 public DataTable CallDb string connStr string sql var dt new DataTable var da new SqlDataAdap
  • 以管理员身份运行批处理文件命令错误.exe'未被识别为内部或外部命令

    以管理员身份运行时出错 BackGroundJob exe 不被识别为内部或外部命令 可操作程序或批处理文件 exe和bat文件都在同一个文件夹中 当我运行它而不以管理员身份运行时它会运行 但要安装此 exe 我需要从同一文件夹以管理员身份
  • CQRS 事件溯源:验证用户名唯一性

    我们以一个简单的 账户注册 为例 流程如下 用户访问网站 点击 注册 按钮并填写表格 点击 保存 按钮 MVC 控制器 通过读取 ReadModel 来验证用户名的唯一性 RegisterCommand 再次验证用户名唯一性 这是问题 当然