保障XML上传接口幂等性的四种方式:一、基于唯一请求标识(Request ID)校验;二、基于业务主键哈希值去重;三、基于数据库唯一约束强制拦截;四、基于Token预分配机制。

当调用XML上传接口时,若网络超时或客户端重试机制触发,可能导致同一份XML数据被多次提交至服务端,引发重复处理、数据冗余或状态冲突。以下是保障该接口幂等性、防止重复提交的多种实现方式:
一、基于唯一请求标识(Request ID)校验
服务端在接收请求前,先提取客户端传入的全局唯一请求标识(如UUID),并检查该ID是否已在近期处理记录中存在;若已存在,则直接返回成功响应而不执行业务逻辑,从而避免重复解析与入库。
1、客户端在发起XML上传请求时,在HTTP Header中添加自定义字段 X-Request-ID: 550e8400-e29b-41d4-a716-446655440000。
2、服务端接收到请求后,立即从Header中读取该值,并查询缓存(如Redis)中是否存在以该ID为key的记录。
3、若缓存中存在对应key且value为“processed”,则直接返回HTTP 200及标准成功响应体,不解析XML内容。
4、若缓存中不存在该key,则将key写入缓存,设置过期时间(例如10分钟),再继续执行XML解析与业务处理流程。
二、基于业务主键哈希值去重
针对XML中具有业务唯一性的字段(如订单号、单据编号、设备序列号等),服务端可提取其值并生成确定性哈希(如SHA-256),以该哈希作为幂等键存入缓存;后续相同业务数据上传时,因哈希一致而被拦截。
1、服务端解析XML正文,定位到根节点下标识业务实体的字段,例如
2、将该字段值与固定盐值拼接后计算SHA-256哈希,得到长度固定的字符串,如 a1b2c3d4e5f6...。
3、以该哈希值为key,尝试向Redis写入一个空值并设置NX和EX选项;若写入失败(表示已存在),则拒绝本次请求并返回错误码409 Conflict。
4、若写入成功,则继续执行后续业务逻辑,并在事务提交完成后更新该key的状态为“completed”。
三、基于数据库唯一约束强制拦截
在存储XML解析结果的目标业务表中,对能代表一次上传意图的组合字段(如外部单号+系统时间戳前缀+客户端ID)建立唯一索引;插入时依赖数据库层面的约束报错实现天然幂等控制。
1、在数据库表中添加联合唯一索引,例如对字段 external_ref_id, client_ip, create_hour 建立UNIQUE INDEX。
2、服务端完成XML解析后,构造INSERT语句插入业务记录,使用ON CONFLICT DO NOTHING(PostgreSQL)或INSERT IGNORE(MySQL)语法。
3、若插入因唯一约束冲突失败,捕获SQLSTATE 23505(PostgreSQL)或errno 1062(MySQL)异常。
4、捕获异常后不抛出错误,而是记录日志并返回标准成功响应,表明该次上传已被接受且无需重复处理。
四、基于Token预分配机制
客户端需在上传前先调用专用接口获取一次性有效token,该token由服务端生成并绑定有效期与使用状态;上传时必须携带此token,服务端验证通过后才允许处理XML,并立即将token置为已使用。
1、客户端首次调用 POST /api/v1/upload/token 获取token,响应体中包含 {"token": "t_abc123", "expires_in": 300}。
2、客户端在XML上传请求的Header中携带 X-Upload-Token: t_abc123。
3、服务端收到请求后,先查询Redis中该token是否存在且未被标记为used;若不存在或已标记,则返回401 Unauthorized。
4、若token有效,则执行XML解析与业务处理,并在事务提交成功后,将该token对应的key值更新为 used 并保留原有过期时间。










