Web services 如何在SOA环境中实施实体依赖关系-构建/下载?

Web services 如何在SOA环境中实施实体依赖关系-构建/下载?,web-services,constraints,soa,foreign-key-relationship,data-management,Web Services,Constraints,Soa,Foreign Key Relationship,Data Management,在建立几个模块化和独立的服务时,我面临着实体之间的依赖关系/存储关系的挑战。考虑工作岗位和员工。在我的系统中,员工的工作分配链接(URI)到工作岗位 在我们的应用程序中,工作岗位将由一个独立于员工服务的服务来管理,这导致了约束的挑战,以防止在员工已与该岗位匹配的情况下意外删除工作岗位 我已经设计了一个定制的解决方案,利用一个注册表(它应该有依赖细节等),并在相互依赖的服务中实施一个范例,但是它很复杂。在SOA环境中,如何管理这些相互依赖关系 非常感谢 在某些方面,您的问题可以重新表述为“如何在S

在建立几个模块化和独立的服务时,我面临着实体之间的依赖关系/存储关系的挑战。考虑工作岗位和员工。在我的系统中,员工的工作分配链接(URI)到工作岗位

在我们的应用程序中,工作岗位将由一个独立于员工服务的服务来管理,这导致了约束的挑战,以防止在员工已与该岗位匹配的情况下意外删除工作岗位

我已经设计了一个定制的解决方案,利用一个注册表(它应该有依赖细节等),并在相互依赖的服务中实施一个范例,但是它很复杂。在SOA环境中,如何管理这些相互依赖关系


非常感谢

在某些方面,您的问题可以重新表述为“如何在SOA环境中实施引用完整性”。答案是你不能。这是自治政府的副产品

因此,几乎按照定义,员工服务中的职位与职位服务中的职位并不相同。这其实是一件好事。尽管这两种服务都定义了工作岗位,但它们是从两种不同的能力中定义的,并且可以根据需要自由地开发和发展它们的能力

因此,基于在另一个服务边界内存在类似数据而在一个服务边界内移除数据的硬约束是不可能的(甚至是不可取的)

这一切都很好,但你如何避免员工可能与某个工作岗位“匹配”的情况,而该岗位已经以某种方式发生了变化,无论是通过撤职还是更新

嗯,服务可能对其他服务的更改感兴趣。在这些情况下,服务可以成为彼此的消费者。很明显,员工能力会对工作岗位能力的变化感兴趣

实际上,它们是这个场景中使用得相当好的设计模式。如果业务操作导致更改服务的数据,则该服务可以发布描述更改的事件消息。其他服务可以成为这类事件的消费者,并以自己的方式处理。由于事件处理通常是通过发布子语义实现的,因此任何需要的服务功能都可以订阅事件

在您的示例中,如果某个职位被删除,则可能会发布的事件可以定义为(使用C#):

此事件的使用者实际如何处理它(使用者将采取什么行动)是另一个问题,取决于使用者的能力。例如,您的员工服务可以收集具有此职位的员工列表并标记他们以供审阅,或者将他们添加到“职位重新分配”队列中

您的事件甚至可以包括一个名为
int ReplacedByJobPosition
的字段,该字段将使使用者能够自动更新依赖于删除的职务的任何能力

只要您的事件是通过容错传输(如消息队列)交付的,您就可以相当有信心,尽管您的服务功能之间没有引用完整性,但您的系统作为一个整体应该是完整的

通过以这种方式使用事件,您还避免了对相互依赖关系的集中注册的需要(这听起来像是一个令人讨厌的想法)。每个服务负责发布有关其自身数据更改的事件,依赖关系由使用彼此事件的服务定义

希望这是有帮助的

编辑

在回答你的评论时——虽然我可以看到由另一个服务来处理这个职位的好处:重新分配问题,我看不出这有什么大问题,但有一些考虑

服务边界和业务能力边界自然契合的原因之一是,当您更改业务能力(例如计费过程的更改)时,它通常不会影响其他业务能力(CRM/Finance/etc)。通过引入共享服务,您可以连接到多个功能,您的服务没有定义良好的边界,因此拥有成本较高,因为它需要进行大量更改

此外,您可能会争辩说,业务事件(例如,JobPositionRemoved)的消费者应该对该事件的整个处理负责


事件的处理很可能会触发发布后续事件(如ReviewTaskCreatedForEmployeeChange),如果需要,该事件可以由另一个使用者(如工作流工具)处理

汤姆,谢谢你的回复。这大大有助于解决问题。跨服务引用完整性的基于事件的方法听起来是一条可行之路。后续问题:您对建立共享服务以管理“职位:分配”关系有何想法(如果我们的规则禁止员工被分配到某个职位,则该职位将被删除。鉴于我们的系统中既没有“工作地点”也没有“员工”将被删除,共享服务对位置/员工的引用将是“引用”而不是“约束”。有什么想法吗?再次感谢!很高兴您发现有用。请参阅我答案的更新。
class JobPositionRemoved
{
    int JobPositionId { get; set; }
    string JobPositionName { get; set; }
    ...
}