我正在尝试设计一个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
标头,这意味着我应该尝试提交。
据我所知,我有两个选择:
If-Match
会导致非2XX / 412响应,也会返回412。 (这是我倾向于的那个)还有其他想法吗?我是否误解了规格?
答案 0 :(得分:3)
不会像“更新除非修改”(乐观锁定)这样的工作吗?实体需要在数据库中存储版本号或etag。
运行不需要提交的验证,忽略etag,必要时返回错误
更新实体,其中id =:the_id和etag =:expected_etag
对于受影响的行返回0或1
如果0资源已经看到并发更新(或者id完全错误,您可以单独检查)。在这种情况下,返回412
提交
如果提交失败,则根据需要返回错误
答案 1 :(得分:0)
也许这在某种程度上是在理论方面,但基于我目前对HTTP规范的理解,我会将类似If-Match的标题的使用分类为几乎不可用于所有但可能是安全的方法,因为:< / p>
“如果请求没有If-Match标头字段,则会产生2xx或412状态以外的任何内容,那么必须忽略If-Match标头”。
为什么呢?仅仅因为在大多数实际情况中,如果执行请求,就无法预见会发生什么。
作为一个例子,谁可以预见IO级错误或必须运行的代码中出现的一些例外情况?
如果将5xx添加到2xx和412,它会更“可解”。