我已经构建了一个API,其中客户端将指示服务器更新数据库中的某个实体,并且它必须容纳多个尝试操作相同数据权限的用户,可能是“同时”。
这是分布式用户竞争条件问题。 (类似于Wordpress如何处理“锁定”博客文章,因为其他用户正在编辑它们。)
示例数据实体
function mutation(arr) {
var arr1 = arr[0].toLowerCase().split('');
var arr2 = arr[1].toLowerCase().split('');
for(var i of arr2)
if(arr1.indexOf(i)===-1)
return false;
return true;
}
mutation(["hello", "hey"]);
在数据实体上运作
例如,客户端会告诉服务器{
versionID : 12345,
type : "building",
name : "The CN Tower"
}
任何给定实体的update
属性。
为了处理多个尝试更改同一实体的用户 - 没有用户意外覆盖彼此的更新 - 每个用户必须发送name
请求update
(也可能称为数据库实体的versionID
)它在加载到UI时从服务器获取它(或者在CLI应用程序的情况下以其他方式存储在客户端)。
这样,如果stateID
在Client A
之前更新了建筑物,服务器就能告诉Client B
他们的更新请求失败了,因为他们正在尝试更新不是数据库中此类记录的当前(规范)状态。
问题
当任何用户尝试更新过渡时已被其他用户更新的数据库记录时,服务器中的正确http status code是什么?
答案 0 :(得分:3)
我认为API应该以409 Conflict Error回复,同时包括正文中资源的最新状态(在您的情况下构建),以帮助识别消费者的最新版本。
答案 1 :(得分:1)
在这种情况下,服务器应回复412 Precondition Failed
状态代码。
它通常适用于以下标题(与请求一起发送):
服务器检查上面提到的一个头的值,如果匹配到客户端,则允许修改资源,否则应该返回412
。
因此A
想要编辑C
,其中ETag
等于10
。服务器接受此请求,编辑C
计算新的ETag
,例如11
并将资源发回。现在,如果B
想要编辑C
ETag
等于10
,则会收到412. B
应该同步资源C
并尝试再次编辑它。