服务在SOA中共享数据库是不好的做法吗?


17

我最近一直在阅读Hohpe和Woolf的企业集成模式,Thomas Erl的一些关于SOA的书,以及观看Udi Dahan等人的各种视频和播客。在CQRS和事件驱动系统上。

我工作场所中的系统耦合度很高。尽管理论上每个系统都有其自己的数据库,但是它们之间有很多连接。实际上,这意味着所有系统都使用一个庞大的数据库。例如,只有一张客户数据表。

我读过的大部分内容似乎都建议对数据进行非规范化处理,以便每个系统仅使用其数据库,并且使用消息传递将对一个系统的任何更新传播到所有其他系统。

我认为这是在SOA中强制执行边界的一种方法-每个服务都应该有自己的数据库,但是我读到以下内容:

/programming/4019902/soa-joining-data-across-multiple-services

这表明这是错误的做法。

隔离数据库似乎是解耦系统的一种好方法,但是现在我有点困惑。这是一条好路吗?是否曾经建议过在SOA服务,DDD绑定上下文,应用程序等上隔离数据库?


您链接的原始问题是错误的。这个问题本身是错误的,因为大多数答案都无法回答。SOA并不是将单个应用程序拆分为离散服务并对其数据进行分区。
杰里米(Jeremy)

我知道问题是错误的,正是这些答案使我重新评估了自己的想法。
Paul T Davies,

我认为,服务必须耦合
乙七

Answers:


12

去耦仅在确实存在分离时才有效。考虑一下您是否有订购系统:

  • 表:客户
  • 表:订单

如果这就是您的全部,就没有理由将它们分离。另一方面,如果您有这个:

  • 表:客户
  • 表:订单
  • 表格:CUSTOMER_NEWSLETTER

然后,您可能会说ORDER和CUSTOMER_NEWSLETTER是两个完全独立的模块(订购和营销)的一部分。将它们移动到单独的数据库(每个表一个)中,并使两个模块共享对自己数据库中公共CUSTOMER表的访问权限,也许是有意义的。

通过这样做,您可以简化每个模块,但是却增加了数据层的复杂性。随着您的应用程序越来越大,我可以看到分离的优势。将会有越来越多的“数据岛”彼此之间毫无关系。但是,总会有一些数据横切所有模块。

将它们放置在不同的物理数据库中的决定通常是基于现实世界的限制,例如备份频率,安全性限制,复制到不同的地理位置等。我不会仅仅因为关注点分离而将表分成不同的物理数据库。可以使用不同的模式或视图更简单地进行处理。


5
-1。仅在有理由将它们放置在单独的数据库中时,它们才应位于单独的数据库中。您需要“从中获得一些好处”,因为这肯定会使您的应用程序更加复杂。
scottschulthess 2012年

1
我认为值得强调的是在数据层分离功能的两个区域的重要性(无论使用单独的架构还是其他)。每个模块仅应通过另一个模块的API访问另一个模块的数据-这类似于OO封装原理。即,不要在多个模块之间共享架构。另外,我建议不要使用视图,而建议通过公开数据。API。
克里斯·斯诺

@scottschulthess是的,您需要权衡复杂性成本,如果不值得,则根本无法拆分为服务。拆分但使用我发现的共享数据库是这三个选项中最差的。
精金

8

我在哪里工作,我们有一个ESB连接到6个不同的应用程序(或者我应该说“端点”)。这6个应用程序可以在2个数据库实例上使用3种不同的Oracle模式。其中一些应用程序共存于同一模式中,不是因为它们相互关联,而是因为我们的数据库基础结构是由外部提供商管理的,而获得新的模式将永远耗费时间(当然,我们当然也没有DBA访问权限)...它确实花费了这么长时间,以至于我们曾经考虑过“暂时”重用现有架构以能够继续开发。为了强制数据“分离”,表名带有前缀,例如对于客户来说是“ CST_”。另外,我们必须使用基于某些正当理由无法进行绝对更改的架构。我知道这很奇怪。当然,就像往常一样,“暂时”

我们不同的应用程序连接到各自的数据库架构并使用其自己的PL / SQL包,我们绝对禁止自己直接与应用程序域外的表/数据进行交互。

当连接到ESB的应用程序之一需要其域外的信息时,即使该信息实际上处于同一模式中,它也会调用ESB上的相关服务来获取数据,理论上只需要在其中添加一些join语句即可。 SQL请求之一

我们这样做是为了能够将我们的应用程序域划分为不同的模式/数据库,并且为了使ESB上的服务在发生时仍能正常工作(即将到来的圣诞节,我们不知所措)

现在,从外部看,这看起来很奇怪,但是有很多原因,我只是想分享这一具体经验,向您展示一个或多个数据库并不那么重要。等等,是!,原因有很多(Scott Whitlock +1,请参阅有关备份的最后一段,这样mya会给您带来麻烦)但是我认为同样重要的是,要正确设计您的SOA服务,至少我是这样认为的,不是DBA。最终,您所有的数据库都属于您的“企业数据仓库”,对吗?

最后,我不会改写Scott Whitlock的最后一段,尤其是

我不会仅仅因为分离关注点而将表分离到不同的物理数据库中。

真的非常重要。如果没有理由,请不要这样做。


8

由于数据集成,我已经看到了软件体系结构中可能发生的最糟糕的噩梦,而到目前为止,我遇到的最好的武器就是针对此类DDD-Style Bounded Contexts。从某种意义上说,这与“正确完成SOA”并不遥远。

但是,数据本身并不是解决问题的最佳方法。人们应该关注预期/需要的行为,并将数据放在重要位置。我们可能最终会以这种方式进行一些重复,但是与几乎总是与数据集成体系结构相关联的系统发展障碍相比,这通常不是问题。

简而言之:如果您正在寻找松散耦合的系统,请不要保持数据耦合。选择weel封装的系统和介于两者之间的结构良好的通信通道,充当“通用语言”。


1
然后……直接回答标题问题:“是的,我认为在SOA中共享数据库是一种冒险的做法”。如果看起来最合理,那可能存在一些严重的设计缺陷。
ZioBrando 2011年

7

解耦数据库并使它们之间的数据保持一致是专家级的任务。当前系统旨在避免这种情况,很容易出错并最终导致重复等问题。坦白地说,采用一个工作系统并执行此操作几乎可以保证引入新错误,而这些错误对用户没有任何实际价值。


1

如果做得正确,将业务关注点分离到不同的数据库(或至少是不同的模式)是一种优点

请参阅Martin Fowler对CQRS模式的描述

随着我们的需求变得越来越复杂,我们逐渐摆脱了[处理像CRUD数据存储之类的信息系统]的需求。CQRS引入的更改是将概念模型拆分为单独的模型,以进行更新和显示。这里。内存模型可以共享同一数据库,在这种情况下,数据库充当两个模型之间的通信。但是,他们也可以使用单独的数据库,通过实时ReportingDatabase有效地构成查询端的数据库。在这种情况下,两个模型或其数据库之间需要某种通信机制。

NServiceBus架构原则

命令查询分离

避免此问题的解决方案可以在系统级别(甚至在客户端和服务器之上)将命令和查询分开。在此解决方案中,有两个跨客户端和服务器的“服务”-一个负责命令(创建,更新,删除),另一个负责查询(读取)。这些服务仅通过消息进行通信- 一个不能访问另一个的数据库...

命令和查询责任隔离(CQRS)

命令和查询责任分离

与写入数据相比,大多数应用程序读取数据的频率更高。根据该声明,最好提供一个解决方案,在该解决方案中,您可以轻松地添加更多数据库以供读取,对吗?那么,如果我们建立一个专用于读取的数据库怎么办?更好 如果我们以某种方式设计数据库以便更快地读取数据库怎么办?如果您基于CQRS架构中描述的模式设计应用程序,那么您将拥有一个可扩展且读取数据快速的解决方案。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.