if-match HTTP标头是否需要两阶段提交?

时间:2012-08-06 01:00:07

标签: http rest transactions optimistic-locking

我正在尝试设计一个RESTful Web API,所以我一直在研究rfc2616。我喜欢使用ETags进行乐观并发的想法,并且试图使用它来创建一种安全的方式来添加没有竞争条件的资源。但是,我注意到section 14.24中的以下两个陈述:

  

如果请求在没有If-Match标头字段的情况下导致除2xx或412状态以外的任何内容,则必须忽略If-Match标头。

     

用于更新资源(例如,PUT)的请求可以包括If-Match头字段,用于表示如果对应于If-Match值的实体(单个实体标签)则不应该应用请求方法不再是该资源的代表。

我正在使用RDBMS并且在我尝试之前不知道事务是否会成功提交,所以我认为第一个要求似乎有点繁琐。考虑一个人为If-Match标头提供不匹配的ETag的情况:如果提交成功,那么我应该注意If-Match标头,不要尝试提交,然后返回412.如果提交失败,那么没有If-Match标头的请求会导致非2XX / 412响应,所以我必须忽略If-Match标头,这意味着我应该尝试提交。

据我所知,我有两个选择:

  1. 使用两阶段提交来预先判断提交是否会在尝试之前成功。
  2. 忽略上面的第一个要求,即使忽略If-Match会导致非2XX / 412响应,也会返回412。 (这是我倾向于的那个)
  3. 还有其他想法吗?我是否误解了规格?

2 个答案:

答案 0 :(得分:3)

不会像“更新除非修改”(乐观锁定)这样的工作吗?实体需要在数据库中存储版本号或etag。

  1. 运行不需要提交的验证,忽略etag,必要时返回错误

  2. 更新实体,其中id =:the_id和etag =:expected_etag

  3. 对于受影响的行返回0或1

  4. 如果0资源已经看到并发更新(或者id完全错误,您可以单独检查)。在这种情况下,返回412

  5. 提交

  6. 如果提交失败,则根据需要返回错误

答案 1 :(得分:0)

也许这在某种程度上是在理论方面,但基于我目前对HTTP规范的理解,我会将类似If-Match的标题的使用分类为几乎不可用于所有但可能是安全的方法,因为:< / p>

  

“如果请求没有If-Match标头字段,则会产生2xx或412状态以外的任何内容,那么必须忽略If-Match标头”。

为什么呢?仅仅因为在大多数实际情况中,如果执行请求,就无法预见会发生什么。

作为一个例子,谁可以预见IO级错误或必须运行的代码中出现的一些例外情况?

如果将5xx添加到2xx和412,它会更“可解”。