我们的客户遵循SOA原则,并设计了非常精细的设计Web服务,如createCustomer,deleteCustomer等。
我不确定细粒度服务是否可取,因为它们会产生与事务相关的问题。例如如果业务需求是每个客户在创建时必须拥有地址。因此,在这种情况下,表示组件将首先调用createCustomer,然后调用createAddress。这些服务在内部使用简单的JDBC来更新db中的相应表。由于服务是由外部组件调用的,因此无法在此处满足事务性要求,即如果createAddress失败,则必须回滚createCustomer操作。
我想,处理此问题的方法之一是设计课程粒度服务(在单个JDBC事务中创建客户和关联地址)或 或许简单地创建一个反转服务(deleteCustomer),简单地反转createCustomer的动作。
任何建议。感谢
答案 0 :(得分:3)
简短的回答:服务的设计应该是为了方便服务客户。如果客户被告知“打电话给这个,那么请不要忘记称之为”你的生活太难了。应该有一个粗粒度的服务。
答案很长:客户可以合理地输入没有地址吗?所以我们打电话给
createCustomer( stuff but no address)
结果是客户的有效(如果可能不理想)状态。后来我们打电话给
changeCustomerAddress ( customerId, Address)
现在持久的客户更有用。
在这种情况下,API很好。关键点在于系统的完整性不依赖于客户端代码“记住”做某事,在这种情况下添加地址。但是,我们更有可能不希望系统中的客户没有地址,在这种情况下,我认为服务有责任确保这种情况发生,并为调用者提供错误的最小可能性。
我会看到一个粗粒度的createCompleteCustomer()方法,这是迄今为止最好的方法 - 这允许服务提供者一次解决问题,而不是要求每个客户端程序员实现逻辑。
备选方案:
A)。有针对原子事务的Web服务规范,主要供应商确实支持这些规范。原则上,您实际上可以使用细粒度方法和真实事务来实现。实际上,当你走这条路时,我认为你进入了一个复杂的世界。
B)。 @mtreit提到的有状态接口(工作,工作,提交)。一般而言,有状态会增加复杂性或妨碍可扩展性。服务在哪里保持中间状态?如果在记忆中,那么我们需要对特定服务实例的亲和力,从而引入缩放和可靠性问题。如果在某些州或正在进行的数据库中,那么我们将具有显着的额外实施复杂性。
答案 1 :(得分:2)
好的,让我们开始吧:
我们的客户遵循SOA原则和 有非常好的设计Web服务 细粒度如createCustomer, deleteCustomer等。
不,客户忘记了达到SOA原则并提出了大多数人所做的事情 - 一系列定义错误的界面。对于SOA原则,clinent将会进入更粗糙的界面(例如OData meachsnism来更新数据),或者遵循任何有关过去25年编写的多层架构的书籍的建议。 SOA只是用CORBA发明的内容和SOA家伙今天所做的所有错误的另一个词,其中10年前基于众所周知的设计愚蠢与CORBA。并不是说今天做SOA的任何人都听说过CORBA。
我不确定是否有细粒度的服务 他们创造时是可取的 交易相关问题。
仅适用于不支持Web服务的用户和平台。认真。如果你 - 在编程中忽略交易问题,你自然会遇到交易问题。这里的诀窍是食物链上的人没有,只是你的客户决定忽略常识(再次,请看我对Corba的第一句话)。
设计Web服务的人非常了解事务性问题,这就是为什么Web服务规范(WS *)包含实际处理事务完整性的机制,方法是将提交操作移动到调用Web服务的客户端。您的客户和您应该阅读的特定规范是WS-Atomic。
如果您使用当前技术来公开您的Web服务(在MS平台上的a.k.a. WCF,Java世界中存在类似的技术),那么您可以将事务流信息公开给客户端并让客户端处理事务划分。这有一个共同的问题 - 就像客户端保持交易恶意开放一样 - 但它仍然是处理在客户端定义的事务的唯一方法。
由于你没有提供任何平台并且只提到java,我指的是一些MS示例如何看起来: http://msdn.microsoft.com/en-us/library/ms752261.aspx
总的来说,Web服务比SOA大多数人想到的要强大得多,而且要考虑得更多。他们看到的大多数问题很久以前就已经解决了。但是,SOA只是多层架构的热门话题,但大多数人认为这是最好的事情,因为切片面包甚至不知道大约10年前的情况。作为您的客户,我会更加关注性能方面。像他定义的细粒度非语义Web服务是非随意使用的性能需求,因为您通过网络询问/更新小的小小东西的次数会使网络延迟对您造成伤害。在这种情况下,为10个商品创建订单可以轻松地进行30-40次网络呼叫,这可能会花费很多时间。 SOA从一开始就宣扬(如果你忽略了那些不了解历史的人),不要使用细粒度的调用,而是要粗略地交换文档和/或语义方法,就像OData系统一样。 / p>
答案 2 :(得分:0)
如果需要事务性,那么可以在服务器上实现事务语义的粗粒度单个操作实现起来要简单得多。
那就是说,当然可以构建一些方案,其中在所有必要的细粒度操作都成功之前,不会提交操作的目标。例如,有一个Commit操作,它检查与服务器上的对象关联的一些标志;在事务中的所有必要步骤完成之前,不会设置该标志,如果未设置该标志,则Commit将失败。
当然,如果轻量级,细粒度的操作是一个重要的设计要求,也许应该重新考虑具有事务性的需求。