在面向服务的体系结构(SOA)下,我对服务是否应该拥有自己的数据感兴趣。
其中一个限制是,如果在任何时候出现任何问题,我们需要能够将整个系统的状态恢复到先前状态,以便我们可以重试或恢复操作。
如果每个服务都拥有自己的数据,那么这是否意味着系统从程序员的角度更好地处理变更?
但是,如果每个服务都拥有自己的数据,是否有任何机制将整个系统回滚到先前状态,以便可以恢复或重试失败的操作?
答案 0 :(得分:2)
听起来,您所谓的服务的粒度可能是错误的。单个服务可以具有多个端点(使用相同或不同的协议),并且如果在一个端点上接收的消息需要在另一个端点上接收的回滚状态,则它仍然是服务边界内的内部事务。
如果我们考虑订单和客户服务的简单示例。订单服务可能与包含整个订单或订单行的消息签订合同,取消订单将撤消受两者影响的状态。通常,客户服务中的地址更改不会随之回滚。
有时,服务操作会在较长的业务流程中捆绑在一起,要继续上面的示例,我们还要添加一个发票服务。所以当我们取消订单时,我们也想取消发票。然而,重要的是要注意,发票服务领域内的业务规则可以表现得不同,例如并且不“回滚”,例如,延迟取消订单可能需要取消费用。我称之为saga的这种长期互动(您可以看到该模式的草稿here)
另请注意,服务之间的分布式事务通常不是一个好主意,原因有多种(例如,为您不一定信任的外部方保留锁定),您可以阅读有关here的更多信息
答案 1 :(得分:1)
您在此处提出的问题(部分)由两阶段提交协议解决(请参阅wikipedia article)
为避免实现此复杂算法,您可以将架构服务之一专用于数据管理。如果需要在不同数据库之间进行数据同步,请尝试在最低层(即系统或DBMS)上进行数据同步。
答案 2 :(得分:1)
SOA系统在一个系统中定义更多服务。这可以提供更多的自治服务,以便每个服务都可以托管在不同的机器上。
但这并不意味着您无法为可以指向一个存储的所有(域)模型提供统一持久层=>当整个系统扩展到一个系统的更多计算机或事务时,简单的业务事务。
在重构期间,自治域模型除了其他内容之外是有用的,以避免一个模型中的更改导致另一个服务的更改的情况=>整个应用程序的全局变化。
答案 3 :(得分:1)
简而言之:否。服务不“拥有”数据。
数据是关于世界的真理,并且隐含着持久和共享。逻辑服务(API)并不总是以1-1方式映射到实际数据。物理服务(代码)是非常可重构的实现,它反对数据的持久性。
对数据进行分区时,会失去描述能力和分析洞察力。但真正杀死你的地方就是诚信。在扩展时,数据无法在孤岛之间保持一致。对于复杂数据,您需要这些外键。
换句话说:平台只有一个“逻辑”DB(每个环境),因为只有一个Universe。分解数据库有许多正当理由,例如硬件限制,性能,协调,复制和合规性。但要把它们视为必要的邪恶,只在需要时使用。
但我认为您可能会问一个不同的问题:“长期运行的基于数据的交易应该由单一权威服务管理吗?”通常,答案是:是的。该事务服务可以实现多个步骤,以便在其认为合适时对流进行排序,例如两阶段提交。您的所有其他服务都应该使用该事务服务来执行事务。
BUT!该事务服务必须仅使用原子语义作为共享资源与DB交互。这包括所有事务状态(意图,然后是操作,然后是结果),以便可以进行恢复和回滚。必须授权数据库在发生故障时保持完整性。我不能强调这一点:如果你想要容错,那么一切都必须分解成原子数据库操作。