每个用户都有一组宝石。这些宝石可以通过 REST API 访问:
GET /user/<user id>/gem -> get all gems
GET /user/<user id>/gem/<gem id> -> get an existing gem
POST /user/<user id>/gem -> add a new gem
PUT /user/<user id>/gem/<gem id> -> edit an existing gem
DELETE /user/<user id>/gem/<gem id> -> delete an existing gem
我有几个后端进程,它们同时运行,并可以通过
POST
HTTP方法添加gem。 (它们也可以编辑(PUT
)或删除(DELETE
)gems,但这对我的问题不重要。实际上,它很重要。请继续阅读。)从高层次来看,它们执行以下操作:
1. GET /user/<current user id>/gem
2. some calculations, based on step 1
3a. if (step 2 decided that a gem should be added)
3b. POST /user/<current user id>/gem
正如所说,这些进程并行运行。通常情况下,两个进程不会管理同一用户的宝石,但也可能发生。
因此,如果在此期间有任何更改,我需要一个机制来禁止步骤
3b
中的POST
。 我考虑使用ETags和乐观锁定:1. GET /user/<current user id>/gem and remember the returned ETag
2. some calculations, based on step 1
3a. if (step 2 decided that a gem should be added)
3b. POST /user/<current user id>/gem with header 'If-Match=<ETag from step 1>'
3c. if (server returns 412 - precondition failed)
3d. start again at step 1
我不确定ETags是否适用于此。大多数ETag的示例都只涉及单个资源(例如/gem/23
),而不是一组资源(例如/gem
)。也就是说,在步骤3b
中,我提供了完整宝石集合的ETag,而实际上我只提供一个要添加的宝石。