1

我正在尝试设计一个 RESTful Web API,所以我一直在研究rfc2616。我喜欢使用 ETags 进行乐观并发的想法,并试图用它来以一种安全的方式添加资源而没有竞争条件。但是,我注意到第 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. 忽略上面的第一个要求,并返回 412,即使忽略If-Match会导致非 2XX/412 响应。(这是我倾向于的那个)

还有其他想法吗?我误解了规格吗?

4

2 回答 2

3

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

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

  2. 更新 id = :the_id 和 etag = :expected_etag 的实体

  3. 这将为受影响的行返回 0 或 1

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

  5. 犯罪

  6. 如果提交失败,则酌情返回错误

于 2012-08-06T01:09:13.750 回答
0

也许这在理论上有点,但根据我目前对 HTTP 规范的理解,我会将类似 If-Match 的标头的使用归类为几乎不可用的所有方法,但可能是安全方法,因为:

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

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

例如,谁能预见到必须运行的代码中出现的 IO 级错误或某些异常情况?

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

于 2013-04-30T09:54:09.990 回答