I'm trying to design a RESTful web API, so I've been studying rfc2616. I like the idea of using ETags for optimistic concurrency and was trying to use it to make a safe way to add resources without race-conditions. However, I noticed the following two statements in section 14.24:
If the request would, without the If-Match header field, result in anything other than a 2xx or 412 status, then the If-Match header MUST be ignored.
A request intended to update a resource (e.g., a PUT) MAY include an If-Match header field to signal that the request method MUST NOT be applied if the entity corresponding to the If-Match value (a single entity tag) is no longer a representation of that resource.
I'm using a RDBMS and don't know whether a transaction will successfully commit until I try it, so I think the first requirement seems a bit onerous. Consider a case where somebody supplies an If-Match
header with mismatched ETags: If the commit would succeed, then I should heed the If-Match
header, NOT attempt the commit, and return 412. If the commit would fail, then a request without the If-Match
header would have resulted in a non-2XX/412 response, so I MUST ignore the If-Match
header, meaning I should attempt the commit.
As far as I can figure out, I have 2 options:
- Use 2-phase commits to gain foresight into whether the commit will succeed before attempting it.
- Ignore the first requirement above, and return 412 even if ignoring
If-Match
would have resulted in a non-2XX/412 response. (this is the one I'm leaning towards)
Any other ideas? Am I misinterpreting the specs?