You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何控制毫秒/微秒级并发场景下的重复API调用

并发重复提交问题解决方案

针对你遇到的POST API并发重复插入问题,结合不能加唯一约束、校验逻辑无法全量放入事务的限制,给你几个可落地的方案:

1. 分布式锁+幂等键拦截

  • 实现逻辑:
    1. 针对每个请求生成唯一幂等键:用客户唯一标识(如ID)+ 请求核心业务参数(如客户手机号、提交的业务单号)做哈希(比如MD5/SHA256),作为该请求的唯一标识。
    2. 用Redis这类分布式缓存实现锁机制:请求到达时,先尝试用SETNX(或Redis Redlock)获取以幂等键为Key的锁,锁的过期时间设置为业务处理的最长耗时(比如5秒)。
    3. 拿到锁的请求进入正常校验+插入流程;未拿到锁的请求直接返回"重复提交"提示,或等待锁释放后再次校验(根据业务需求选择)。
  • 注意点:
    • 锁的过期时间必须大于业务最长处理时间,避免锁提前释放导致重复;如果处理超时,可考虑续锁机制。
    • 封装通用拦截器/注解,让上百个API快速接入,不用逐个修改业务代码。

2. 缓存标记前置拦截

  • 实现逻辑:
    1. 首次请求通过校验后,在缓存中写入一个标记(Key为客户标识+业务类型,Value为"PROCESSING"),过期时间设为业务处理最长耗时。
    2. 后续相同客户的相同业务请求到达时,先查询缓存:如果存在标记,直接拦截;如果不存在,再进入校验流程。
    3. 业务处理完成(无论成功失败),删除缓存标记;如果服务异常崩溃,依赖缓存过期自动清理标记,避免永久拦截。
  • 优势:比分布式锁更轻量,无需等待锁释放,直接快速拦截重复请求。

3. 数据库行级锁实现伪排他校验

  • 实现逻辑:
    1. 在核心业务表(比如客户主表)新增一个processing_flag字段(类型为VARCHAR或BOOLEAN,默认NULL)。
    2. 请求到达后,先执行UPDATE customer SET processing_flag = 'LOCKED' WHERE customer_id = ? AND processing_flag IS NULL,判断影响行数:
      • 影响行数>0:说明拿到了排他权限,进入校验+插入流程;
      • 影响行数=0:说明已有请求在处理,直接返回重复提交。
    3. 事务提交/回滚后,processing_flag会自动恢复为NULL(因为UPDATE在事务内执行),无需手动清理。
  • 注意点:无需引入额外组件,利用数据库自身的行锁机制,适合不想增加缓存依赖的场景。

4. 请求排队+消费端去重

  • 实现逻辑:
    1. 在API入口层(网关/服务入口)将请求发送到消息队列(如Kafka/RabbitMQ),用客户标识+请求哈希作为消息的Key。
    2. 消息队列的同一Key消息会被分配到同一个分区,消费端串行处理该分区的消息。
    3. 消费端处理前,先查询本地缓存/数据库是否已处理过该请求(用幂等键判断),如果已处理则直接跳过,否则执行校验+插入。
  • 优势:适合高并发场景,能削峰填谷,同时天然保证同一客户的请求串行处理,避免并发冲突。

内容的提问来源于stack exchange,提问作者Vman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 19:37:17