对于 REST 和其他方法(尤其是Web 服务)孰优孰劣的讨论已持续了很长时间。简言之,在基于Web 的集成中使用REST 的优势何在。讨论继续进行着,但是一些人开始把讨论转移到在 REST(或 REST/HTTP)是否丢失了其他方法中存在一些理应具备的能力。分布式事务是其中之一,最近,一个 REST 讨论的邮件列表正来来回回地进行着,这个讨论是由 Bill Burke 就一个基于 RESTeasy 的实现向人们征求意见引发的。
相当简洁的 API。我想看到 Atom 链接是否可以取代已发布的 URI 模式,那样我们就可以限制系 统所暴露的 URI 的数量,使得它从整体上更灵活。 我还在想我们是否能标准化链接关系(Link Relationships)而不是数据格式,这样可能就能使 DTX 标准从必须一并定义数据格式的限制中解放出来。
这篇发文引发了一场围绕着 ACID 事务和基于补偿的事务之间的选择的踊跃讨论, Bob Haugen(ex-Choreology and OASIS BTP) 指出:
基本步骤:1:第一步,所有的参与者临时更新资源(不是通过状态,就是通过独立的临时资源)2 :一旦提交,所有的参与者更新资源的最终状态(或者创建“最终资源”)3:一旦放弃或取消,所有参与者删除临时资源,或者将临时资源标记为“已取消”,或者创建新的“已取消资源”。 这种模式还允许选择性地提交或取消,比如在竞价流程中使用。
似乎达成一致的是,基于和 Web 服务相同的原因,如果需要事务,那么扩展事务(补偿是一个具体的例子)将是可能的发展方向。 Mike Amundsen 补充道:
我更倾向于 Saga 模型,因为它是一个“乐观的”模式,而且我发现它在 HTTP 上建模更简单。从实用性来说,我可以不需要使用 saga 的细节(实现“向前补偿”或“向后补偿”)就可以为最初的交互建模。之后(有时是几周之后或几个月之后)在实施时,我可以在不影响客户端或代理的情况下添加补偿任务。
后来 Roy Fielding 也加入了讨论,他在几年前曾经说过……
这个话题多次出现在 webdav 和 http-wg 列表上。事务是一个资源,但是它和被请求资源之间的关系可以通过一个消息头字段来定义,该消息头把每一次请求定义成层级事务之中的顺序资源。换言之,服务器开始一个事务,每一次请求,将(事务的)URI 作为包含着请求号的消息头的字段传送给客户端,最后通过向事务的 URI 发送一个最终请求来取消或提交事务。我在 still-vapor waka 协议中基本上是这么做的。
然而时过境迁,Roy 的观点也有所变化。
如果你需要分布式事务的协议,那么你怎么可以说你的架构是基于 REST 的呢?简单来说,我看不到你如何能够从一种情形(在客户端使用 RESTful 应用状态,使用超媒体来决定状态间的过渡)到另一种情形(需要事务语言的分布式约定,而客户端如何告诉服务器来管理(客户端)的资源)。你正在考虑的问题很可能是多服务器之间的 CRUD 操作,而每次操作都是基于 RESTful 架构的。当所有操作完成时,客户端需要发起最后的请求来取消或确认(之前做的)更改,可能是与一个 TM 式(TM-Style)的管理资源交互,通知所有的服务提交所做的更新,从而使这组资源进入一个更持久或者公开的状态,就像登台服务器(staging server,即负责整个处理中某阶段工作的服务器)被用来准备要发布的内容。所有这些操作加起来可能等同于一个 ACID 事务。而它们跟 REST 客户端没有任何关系。就 REST 客户端而言,它在一个时刻只和一个资源交互,尽管有时候这些交互可能是重叠的或者异步的。除了依据资源的语义而在后台实现的约定机制之外(存在于独立的架构中,这里我们不关心它),REST 并无“事务协议”;除了为客户端提供(任意点上)的多选择的展现之外,REST 并不包含提交协议。而且,客户端事务协议的约定也没有必要,因为客户端只能在服务端提供的选择范围内进行选择。
这之后还有很多追踪邮件,比如扩展事务协议(不是 ACID)可以以 RESTful 方式用在何处,以及已经使用的何处的跟帖。但是,Bill Burke 插话说,讨论并已偏离了最初的主题:
我最初发帖的目的是,在客户端资源层以及资源 /TM 交互层,如何通过定义以及标准化若干链接关系来大大简化工作。
这似乎得到了一些邮件列表里的人的响应。事实上,后来 Alexandros Marinos 把大家引到一个基于 ACID 的协议,他和他的同事们正在实现这个协议。讨论依然继续着,但对于 REST 世界是否有合适的(扩展)事务,似乎并没有明确的答案。然而,几乎可以定论的是很多人认为分布式事务是需要的,基于某个或某些原因。
查看英文原文: REST and transactions?
评论