如果 REST 上的事务是不可实现的,那么 REST 怎么可能真正有用呢?

在研究 REST 时,可能任何人都会首先注意到,没有定义任何事务语义,有人说这是隐含地违背了 REST 的本质,而其他人说任何这样做的尝试都会导致“污染”REST 系统。

但是为了便于讨论,我们可以说 REST 确实成为了一个流行的‘ api’选择,而且宇宙中的每个站点都开始公开 restful 入口点。

如果没有事务行为(我说的是无补偿) ,这些到底是如何可用的?因为在我看来 REST 的好处之一就是它可以分解数据的组成部分,您可能会认为这使得智能客户机可以从多个服务组合数据(并添加和调整这些组合数据)。但是如果我不能独立地自动地对这种数据组合进行更改,那么使用 REST 就变得毫无用处。

随着时间的推移和对严肃数据公开的需求的到来,我们需要简单的东西(REST 在这里获胜) ,并支持事务行为,这样我们就可以可靠地操作这些数据。

现在,我已经在我的研究中读过几次一个特定的论点,它与我们应该如何在 REST 中考虑事务有关,给出的例子是购物车,在购物车中你隐式地有隔离,因为购物车是你的。

However I disagree with this argument, firstly, the isolation a shopping cart has is merely convenient, this isn't a transaction isolation.. what happens if I'm simultaneously doing an operation against my cart whilst some part of my application is reading data from it? I wouldn't expect the reading part of my application to see data that is 'still in transaction'.

更不用说,并非所有数据更改都有隐式事务模型,多个服务上的事务肯定没有。

在我看来,事务需要发生,而且需要以一种能够让实际的 REST 调用忽略这一事实的方式发生(添加其余的有效负载是一个很大的不可以,但添加头是可以的)。

我阅读了一些关于如何在 REST 上创建事务模型的建议,其中一些正在编写的规范似乎是最近的。

你有什么真正的想法吗?难道不应该有比 REST 更多的东西吗? 这样就可以利用 REST 的简单性来对抗可靠的数据操纵(“酸性”事务)。

如果不是这样的话,我们是否应该加大赌注,告诉服务开发人员,如果他们想要在纯数据世界中交互,他们需要支持像肥皂这样可以说是单一的东西?或者更糟糕的是,尝试将他们自己的定制事务支持构建到诸如 REST 之类的东西中,使得每个服务都变得非标准化,从而打破了 REST 的全部威力?

提前谢谢你的建议。


编辑,添加简短的场景:

假设一个客户端表单处理一个专辑的创建,为了方便在这个专辑上,而不是要求用户为艺术家资源提供 uri,他们可以从一个艺术家列表中选择(很可能是从艺术家目录中获得的)。

For sake of usability the client can write the artist name in manually so they can create an artist 'inline'.. in the posting scenario, the client code understands this, and before sending the request to create the album, it firstly attempts to determine if the artist already exists, if so, gets the uri for that artist, otherwise creates the artist and gets the artists uri.

然后客户端代码继续创建相册,这是比通常的客户端更聪明的,它不是坐在 REST 和“哑”发布之上,而是有一些交互处理更纯粹的 REST 逻辑。

然而,在这种情况下,如果艺术家是第一个被创建的,那么最好保证艺术家不会被创建,除非专辑被创建。

这并不像事务所暗示的那样“关键”,但是它定义了一组工作,客户机代码希望这些工作作为一个操作进行(毕竟,它使得这对用户来说看起来像是一个单独的操作)。

对于这个场景,我看到的唯一指导方针是,在专辑创建失败的情况下,让客户机执行补偿操作,并专门调用删除艺术家。但这似乎有问题,因为客户假设艺术家是孤立的,尽管这可能不太可能,如果另一个客户已经“看到”该艺术家,并分配给它会发生什么?

这些是我关于数据更改的担忧,当然还有其他的空白(谁说艺术家不能只是在稍后的日期删除) ,这些动作是不透明的(即,这些动作不是由客户端自动完成的,而是用户特别要求的)。

我希望这有助于阐明这个话题。

30559 次浏览

看看 OpenStreetMap API。我认为它是一种“ REST”,它提供了一种“事务”——称为“变更集”。这就是你想要的吗?

我知道非常成功的在线会计系统(SaaS) ,它有一个基于 REST 的非事务 API,用于创建、检索和操作发票等。他们因其 API 和易于与其他方面集成系统而广受好评。这个 API 易于维护,可以在各种平台上使用,并且确保向后兼容性相当简单。

事务的缺乏可能是一个真正的痛苦,但大多数时候,当他们的服务器没有太多的加载,API 工作得非常好。

有时候,不够完美就足够了。

这是个有趣的话题。正如您所提到的,SOAP 已经具有这种功能,但是在 SOAP 成熟到人们可以考虑使用它进行真正的安全性和事务处理之前,它花了许多年的时间。在那之前,是 CORBA。

SOAP 的各种高级扩展(包括安全性和事务)需要许多人做大量工作才能做好。这种情况不会一夜之间发生在 REST 身上,而且可能永远也不会发生。

我觉得 REST 目前的流行是对设计不良和过于复杂的 SOAP 实现的一种抵制,这是一种遗憾,因为 SOAP 不一定非要这样。与其他任何东西一样,它需要良好的设计,使其工作得很好。

REST 操作可以启动事务,执行多个数据库或其他事务操作,然后提交或回滚——所有这些操作都在事务范围内。

REST 不能做的是成为事务的根以外的东西。您不能启动一个事务,然后执行两个 REST 操作和一个数据库操作,然后将它们一起提交。这就像澳大利亚的 ASMX 网络服务一样。NET.它们可以是事务的根,但仅此而已。他们成功了很多年,直到引入了 WCF,支持 WS-Transactions。即使在今天,并且使用 WCF,大多数 Web 服务操作在您所询问的意义上也不需要是事务性的。

如果您希望在 ReST 应用程序中使用 ReST API 函数进行事务处理,通常是因为您的技术人员仍在使用 Google。

我们换个角度来看。

肥皂谷歌: 打开事务,创建客户记录,创建订单记录,提交事务。

返回文章页面休息谷歌: 询问服务器该做什么。服务器说“创建客户资源”,所以 POST/客户。服务器说,“现在创建一个订单,如果你想”,客户端通过下面的形式创建订单。

在 REST 中,应用程序协议表示为创建和操作的资源,而不是具有事务边界的数据。

如果您希望有一个跨所有这些操作的长时间运行的事务,那么决定启动它的是 服务器,而不是客户机。

您仍然可以在服务器端实现长时间运行的事务。如果您试图从客户端获取事务,那么假设客户端已经知道它将要执行的所有操作以及这些操作之间存在的事务边界。如果这就是您对客户端的期望,那么您已经放弃了 rest 架构的后期绑定、超媒体驱动的特性。

因此,实际上,如果您不使用 REST 并试图通过 http 来适应 RPC,那么您就会遇到没有事务的问题。

我将假设,当您谈论事务时,您所谈论的是分布式 两阶段提交协议。

如果我理解正确的话,您正在试图理解,如果 REST 不能支持跨不同 REST 请求的事务,我们如何能够使用 REST 来执行跨多个系统的操作。问题是,您正在做出一个潜在的有缺陷的假设,即我们应该使用事务来实现一致性。我们为使用它们付出了什么代价,还有什么替代品存在?

Pat Helland 曾经在亚马逊工作,现在在微软工作,他写了一篇论文 超越分布式事务的生命。提交人在文件中作了以下陈述:

不幸的是,程序员努力 解决像电子商务这样的商业目标, 供应链管理,金融, 和医疗保健的应用 越来越需要思考 非分布式伸缩 他们这样做是因为 尝试使用分布式 交易过于脆弱 表现不佳。

他的论文探讨了分布式事务的替代解决方案,这些解决方案具有伸缩性和良好的性能。

也许 REST 会成功,因为它不支持事务。这里引用了 Roy Fielding 的话,他发明了 REST 这个术语

如果你发现自己需要一个 分布式交易协议 你怎么能说这是你的 体系结构是基于 REST 的 只是看不到你如何能从 (使用 RESTful 的)一种情况 客户端上的应用程序状态和 确定所有状态的超媒体 过渡)到下一种情况 需要分配协议的 事务语义,其中 客户端必须告诉服务器如何 管理自己的资源。

现在我考虑“休息” “交易”是一个矛盾修饰法。

这是2009年6月9日 REST 讨论列表中的一条消息。我不能提供一个链接,因为雅虎组是无用的。

我认为通常需要事务的大多数操作都可以在没有事务的情况下重做。

例如,经典的银行转账,假设我想把100美元从账户 A 转到账户 B:

Begin Transaction
/Debit  A, $100
/Credit B, $100
Commit Transaction

这可以改写为:

/Transfer  A, B, $100

通过这种方式,服务器可以分两个步骤完成这项工作,但是来自客户端的操作是一个单独的原子操作,这在逻辑上是有意义的。

我相信有很多例子可以更方便地执行一组要么全有要么全无的操作(我很好奇人们能想出什么办法来解决这些问题) ,但我通常会以这种方式重新工作。

实际上,REST 中的事务的工作方式与传统 SOAP 服务中的事务是 应该有用的非常相似。

RPC 风格的事务,其中客户机发出一个“开始事务”命令(或一些隐式开始但不提交事务的操作) ,然后是一些额外的操作,接着是另一个隐式/显式的“结束事务”命令,这些都已经过时了。Web 服务世界早已远离了 RPC 模型; 用 SOAP 编码的 RPC/甚至不符合 WS-I!

今天的 SOAP 服务是围绕 信息的概念构建的,而不是 程序。单个消息包含执行完整事务所需的 所有信息。如果您正在提交订单,OrderRequest消息将包含客户信息、订单信息、订单详细信息、付款详细信息... ... 服务器可能需要了解的关于单个订单的所有信息。

我们确实有为分布式事务定义语义的 WS-Transactions,但是它们并不真正意在支持来自客户端的类似 RPC 的语义,它们只是为了当您需要多个服务参与同一事务时的编制服务。例如,您的订单服务需要获得一个支付处理服务来验证信用卡信息并发布付款,如果履行服务发现您的库存不足,或类似的情况,则需要回滚付款。这一切都发生在服务器环境中,因此没有什么可以阻止您在 REST 中做同样的事情。

在 REST 中,使用的是 资源而不是 信息,但是这个概念实际上非常相似。客户端提交(PUT)的不是 OrderRequest消息,而是 Order资源,资源应该包含完成事务所需的所有相同信息。不可否认,如果您试图执行复杂的编排,您可能会发现 REST 与 SOAP 相比有点笨拙,但是这并不意味着您不能继续为 前端使用 REST,只是 SOAP 将为您的 后台服务提供更好的服务。

但实际上,99% 的情况下,人们并不需要 WS-Transactions 的复杂性。我知道这一点,因为我几乎只使用 SOAP (WCF) ,很少使用 WS-Transactions。

在 REST 中,“状态”驻留在客户机上。服务器告诉客户端,“这是创建这个资源(完成这个事务)所需要的所有信息。”但是这个空白表格实际上并不是 开始事务。这取决于客户是否真正提供信息——可以这么说,填写表单。客户机在填写表单时所做的事情与服务器无关; 当客户机最终将完成的表单发送给服务器时,将对其进行完整的验证。它类似于工作单元(Unit of Work) ,只不过客户机是跟踪“工作”的人。

希望本文能够更好地了解如何通过 REST 实现事务和 。它们仅仅依赖于更丰富的消息/资源概念和一种乐观并发形式。

因为不是每个系统都需要事务。

我认为使用 REST 的事务实际上是可以实现的。把事务想象成一个资源,您可以创建(启动)、编辑(通过发布更改)和删除(提交、回滚)。提交到事务的更改在事务提交之前不需要修改全局状态,并且在提交期间,您可以强制执行需要的任何全局状态一致性规则。当然,事务资源将通过授权规则得到保护。

你已经提到了这个概念的一个常见例子:

现在,我已经在我的研究中读过几次一个特定的论点,它与我们应该如何在 REST 中考虑事务有关,给出的例子是购物车,在购物车中你隐式地有隔离,因为购物车是你的。

However I disagree with this argument, firstly, the isolation a shopping cart has is merely convenient, this isn't a transaction isolation.. what happens if I'm simultaneously doing an operation against my cart whilst some part of my application is reading data from it? I wouldn't expect the reading part of my application to see data that is 'still in transaction'.

你为什么不允许观看交易?只要您将其呈现为一个挂起的更改列表,那么提供该特性实际上是有帮助的。但是如果您不希望它是可见的,您可以在资源上禁用 GET