我来尝试回答一下,为什么只是读检查会发生race condition,而只有写入database as primary key才可以正确的检查到是否是相同的idempotency key:
考虑一个用户第一次发出了请求,但是超时了,然后他接着发出了第二次请求,但是第一个请求由于网络堵塞的原因,这个时候才跟第二个请求同时到达服务器。我server端的逻辑是:
try {
db.get(idempotencyKey);
} catch (ObjectNotFoundException e) {
processPayment;
db.write(idempotencyKey);
}
那么在上述的情况下,第一个跟第二个请求都会进入到exception的处理逻辑处,然后process payment。就会发生重复,即使是我后面只成功写入db一个order record。(因为primary key constrains idempotency id)。
那么如果修改成
try {
db.write(idempotencyKey);
processPayment;
} catch (WriteException e) {
return "success";
}
这样只有成功写入idempotencykey到db之后才可以处理payment,否则会返回该order已经成功处理
展开