8

我希望将具有清晰域模型的相对较新的基于 Web 的应用程序转换为更多的 CQRS 样式系统。我的新应用程序本质上是对旧的现有系统的增强替代。

我组织中的现有系统共享一组通用数据库,这些数据库由整个公司孤岛中存在的无数应用程序(通过混沌方法开发)进行更新。(就目前而言,我相信公司中没有一个人可以识别出他们所有人。)

因此,我的问题是关于我的应用程序的读取模型。由于各种状态变化、一般用户数据等都是由我无法控制的其他应用程序更新的,那么以我可以处理外部更新但仍然保持相对简单的方式来处理构建读取模型的最佳方法是什么?

到目前为止,我已经考虑了以下内容:

  1. 在数据库中为读取模型创建视图,读取所有表,旧的和新的
  2. 向现有表添加触发器以更新新的读取模型表
  3. 将一些代码添加到数据库(CLR Stored proc/etc [sql server])以更新外部数据存储以用于读取模型
  4. 放弃希望

关于如何处理这个问题的普遍共识是什么?认为我可以在不从头开始完全重写所有内容的情况下为遗留系统带来秩序是愚蠢的吗?

4

3 回答 3

1

我曾经遇到过类似的情况,以下步骤是我的做法:

要改进遗留系统并实现更清洁的代码库,关键是接手编写责任。但不要太雄心勃勃,因为这可能会引入接口/合同更改,从而使最终部署存在风险。

  1. 如果所有写入都是通过除直接 sql 更新之外的任何方式触发的,请尽可能保持它们向后兼容。将它们作为新开发的命令处理程序的适配器/客户端。

  2. 一些写入是直接的 sql 更新,但您无法控制
    询问负责团队是否可以更改为您的新接口/合同?
    如果不是,请参见步骤 3。

  3. 问他们是否可以容忍最终的一致性并愿意用数据库过程替换 sql 更新?
    如果是,请将所有 sql 更新放入过程中并安排部署,然后查看步骤 4。
    如果不是,也许您应该将它们包含在重构中。

  4. 修改过程,用插入事件替换sql更新。并开发一个后端作业来滚动事件并发布它们。让您的新应用程序订阅这些事件以向您的命令处理程序触发命令。

  5. 从您的命令处理程序发出事件并使用它们来更新其他应用程序曾经使用的表。

  6. 移至遗留系统的下一部分。

于 2014-12-24T04:56:45.240 回答
1

我已经成功使用了选项#1。根据写入数据库的复杂性,创建视图以降低数据的士气以创建读取模型是一个可行的选择。意思是,如果它是大多数开发人员可以理解的相对直接的连接,那么我会仔细看看它是否适合您。我会小心在这些视图中过于复杂。

要考虑的另一件事是定期轮询以构建和更新类似于传统的报告数据库。尽管与通知相比不是最佳的,但取决于您的读取模型的陈旧程度,这也可能是一个可供选择的选项。

于 2014-12-24T02:51:42.137 回答
0

如果我们有一个无限强大的服务器,我们就不会为视图模型而烦恼,而只会从基本实体表中读取。视图模型旨在通过准备和维护适当的数据集进行显示来提高性能。如果您使用数据库视图作为视图模型,那么与即席查询相比,您实际上并没有获得太多的性能提升(如果您忽略了 sql 解析器可以为视图执行的预先计划)。

我的解决方案比@Hippoom 的解决方案侵入性更小,但比@Derek 的响应更快。如果您有权访问遗留系统并且可以进行少量代码更改,则可以添加异步队列写入以在遗留系统存储库中的队列系统(RabbitMQ、Kafka 或其他)中或任何数据被持久化的地方生成事件。使这些写入异步不应引入任何显着的性能成本,并且如果队列写入失败,它不会影响遗留系统。这种变化也很容易通过 QA。

然后编写一个事件驱动的片段来更新您的读取模型。在遗留系统更新阶段(可能需要一段时间),或者如果您只能访问一些写入这些数据库的遗留系统,您可以使用一个小实用程序将新的“UpdateViewModel”事件放入队列中几分钟。然后,当遗留系统保存重要内容时,您将获得及时的事件,但也涵盖您无法更新的系统。

于 2018-06-05T12:18:43.347 回答