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

Laravel 7 + MySQL 5.7 无重复点击场景下插入两条相同数据问题求解

重复插入的数据示例:
示例

问题产生原因

排除用户连续点击后,重复插入通常由以下几类原因导致:

  • 浏览器预加载机制:现代浏览器默认会对用户可能访问的链接做预请求提前加载资源,用户实际点击前接口已经被调用过一次,点击后触发第二次调用,两次请求间隔极短,对应created_at字段几乎完全一致。
  • 服务端配置的重试规则:Nginx/Apache等反向代理如果配置了不合理的重试规则(比如proxy_next_upstream包含了非异常场景、超时阈值设置过短),会导致同一个请求被转发两次到Laravel应用。
  • 前端逻辑异常:如果点击事件重复绑定、事件冒泡未拦截、未做防抖处理,单次点击也会触发两次提交请求。
  • 业务代码逻辑重复:比如插入逻辑被事件监听器、中间件重复调用,或者路由重复绑定了同一处理逻辑。
  • 网络波动触发重试:请求响应超时后,浏览器、前端框架、代理层都可能自动发起重试,导致同一个业务请求被执行两次。
解决方案

建议从前端拦截、后端幂等、数据库兜底三个层面联合处理,彻底避免重复插入问题:

前端优化

  • 提交类操作统一使用POST/PUT请求,不要使用GET请求,GET请求更容易被预加载、爬虫抓取触发意外调用。
  • 点击提交按钮后立即置灰禁用,设置3~5s的冷却时间,避免重复触发。
  • 检查点击事件绑定逻辑,避免组件重复渲染时多次绑定同一事件,必要时添加防抖逻辑。

后端逻辑优化

  • 新增幂等校验机制:前端每次提交生成唯一的request_id随请求传入,后端收到后先校验该ID是否已被处理过(可存在Redis或专门的幂等表中,设置1小时过期时间),已处理则直接返回结果,未处理再执行业务逻辑,处理完成后标记该ID为已处理。
  • 插入数据优先使用Laravel提供的firstOrCreate()、updateOrCreate()方法,通过业务唯一条件匹配后再决定是否插入,避免重复执行写入。
  • 检查反向代理配置,去掉不必要的重试规则,合理设置超时阈值,避免代理层主动重复转发请求。

数据库兜底

  • 针对业务层面的唯一字段组合(例如用户ID+业务标识+操作类型等)建立联合唯一索引,哪怕上层校验全部失效,MySQL也会直接拒绝重复数据的写入,从底层避免脏数据产生。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 07:27:01