【问题标题】:Microservices - How to ensure referential integrity?微服务 - 如何确保参照完整性?
【发布时间】:2019-10-13 22:28:13
【问题描述】:

我正在创建一个个人费用管理器应用。为此,我正在创建一些微服务并采用“database per service”模式。所以,我有:

  • 费用数据库
    • 列是:id、category_id、name、amount、payment_date、details

  • 类别数据库
    • 列是:id、name

我现在面临的问题是:一项费用可以(并且应该)有一个类别。如果服务有自己的数据库,我如何确保给定的费用有一个现有的类别?我现在能想到的唯一方法是:

在费用创建时,我向类别服务发出请求,以验证类别的存在。但是我可以清楚地看到这种方法的一个大缺陷:它可能适用于单一关系,但如果我有四个以上的关系呢?就性能而言,调用其他五个服务来确保完整性将是一团糟。

我不知道如何处理这个问题。有关如何更好地解决此问题的任何建议?

【问题讨论】:

  • 不要将微服务分割成最小的部分。将它们划分为业务领域,而不是“表格”或数据。微服务不是数据库中的表。

标签: rest spring-boot microservices


【解决方案1】:

一项费用可以(并且应该)有一个类别。如果服务有自己的数据库,我如何确保给定的费用有一个现有的类别?

一般来说,你不知道。也就是说,需要一致的信息必须存储在同一个地方(即同一个“微服务”的一部分)。仅当数据不必保持一致时,您才可以将数据分布在多个数据库中。

有时可以接受的一种折衷方案是,我们可以在费用数据库中存储类别信息的缓存副本。这允许您考虑添加约束条件,即费用数据必须与类别数据的缓存副本一致,前提是您可以处理类别数据的副本将过时并且可能因所做的更改而失效的事实到类别数据。

但是强制引用完整性有竞争条件的问题;我提交了“确实”存在但尚未出现在缓存副本中的类别的费用。应该发生什么? “microsecond difference in timing 不应该对核心业务行为产生影响。”

另一种折衷方案是模拟时间——周二的支出可以使用周二有效的类别,即使它在周三不再有效。因此,费用服务可以暂停判断,直到它在适当的时间知道类别是否有效。如果提前计划了费用政策的更改,这是有道理的。

另一种折衷方案是重新组织业务功能的实现,以便与类别相关的行为全部由管理该数据的服务执行。费用服务会知道标识符,但很少知道其他信息。

没有魔法 - 分布式系统需要妥协。

【讨论】:

  • "... 需要保持一致的信息必须存储在同一个地方" - 与用户创建/删除服务和许多其他与用户属性相关的微服务相关联的用户表怎么样和偏好(无论用户是否指定),与用户 ID 的外键相关联。如果突然删除主用户表中的用户/用户 ID,则具有用户首选项的其他表(以及作为 FK 的用户 ID)将失去参照完整性。但与此同时,将所有这些数据存储在同一个地方可能没有意义。想法?
猜你喜欢
  • 2010-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-30
  • 2011-09-17
  • 2014-04-28
  • 1970-01-01
相关资源
最近更新 更多