幂等含义

幂等是指同一项操作重复执行时,系统的最终有效结果与执行一次相同。它不要求每次响应内容完全一致,也不代表服务端不记录重复请求。

网络超时后,客户端无法判断服务端是否已经处理,因此重试是常见行为。没有幂等控制的写操作,可能生成多条记录或多次推进状态。

幂等键

客户端可以为一次逻辑操作生成稳定的幂等键。首次请求到达时,服务端保存该键、请求摘要和处理结果;相同键再次出现时,先比较请求内容,再返回已有结果。

幂等键的作用域要明确,例如按调用身份、接口和时间范围共同判断。不同操作不能意外共享同一个键。

scope = client_id + endpoint + idempotency_key
request_hash = SHA-256(canonical_body)

如果相同键对应的请求内容发生变化,应返回冲突错误,而不是默默使用第一次的数据。

数据库约束

应用层“先查询再插入”存在并发间隙。两个请求可能同时查询到记录不存在,然后同时写入。唯一约束能把最终边界放在数据库中,是实现幂等的重要组成部分。

常见设计是在逻辑编号上建立唯一索引,再在事务中插入。遇到唯一冲突后读取已有记录,而不是直接重复执行业务逻辑。

状态机

状态机把允许的变化写成明确规则。每次更新都需要检查当前状态和目标状态,避免完成后的记录被普通重试改回处理中。

当前状态允许变化说明
已创建处理中、已关闭尚未进入最终结果
处理中已完成、处理失败等待外部或后台处理
已完成保持不变终态通常不逆转
处理失败处理中或保持不变是否重试由明确规则决定

状态名只是示例。关键是所有入口都使用同一转换规则,包括接口请求、后台任务、通知和人工修正。

并发处理

并发控制可以使用条件更新、乐观版本号、行锁或串行化事务。选择取决于冲突频率和性能要求。无论使用哪种方式,都要在数据库写入结果上判断是否真正获得更新权。

UPDATE records
SET status = 'completed', version = version + 1
WHERE id = ? AND status = 'processing' AND version = ?;

受影响行数为零,说明状态已变化或版本不匹配,调用方应重新读取,而不是无条件覆盖。

参考资料