Troubleshooting系列-接口超时导致的重复数据插入问题分析及解决

1.问题现象

现网巡检发现一个接口MethodA超时,执行时间大概花了14秒。查看接口对应的数据,发现有张表TA数据重复。

2.问题定位分析过程

MethodA接口是一个管理台优惠券批次增加可用商品审核接口,审核通过后会将对应商品添加到批次可用商品表中。

分析ELK中日志记录,发现出问题的MethodA调用了两次,其原因是DUBBO默认调用超时后会重试两次,第一次超时后进行重试触发,这样会调用两次。整体时序类似如下:

关于MethodA超时时间配置

dubbo调用超时时间优先级是:对于同一个服务,方法级别>服务级别>全局级别,消费端配置优先于提供端配置。如果级别一样,离调用者越近,优先级越高。

消费者端调用接口的超时时间10s,服务端接口一旦调用,不会取消,因tranctional超时时间没配置,需要等整个事务完成才会结束,在provider端需要14秒,但是cosumer端等待10秒后就会重试一次,第二次大概率会成功。

但是在验证时,请求1'有时10秒就会超时,原因是跑到更新审核表状态时,因请求1将行锁锁住,如果超过10秒不返回,会触发单条sql执行超时,有连接请求sockettimeout指定,刚好也是10秒

sql 复制代码
update t_1 set status = '2' where audit_id = '123';
//audit_id是唯一主键,更新成功,触发行锁,如果更新行数为0,会触发间隙锁

3.问题解决

  1. consumer端将重试次数设置为0,不重试
  2. 事务注解加上超时时间的设置,超时时间小于接口定义的超时时间
  3. 为了防止重复插入数据,增加业务幂等性操作,更新审核表状态时判断执行结果同时条件加上原状态值,使用数据库乐观锁方式,sql改成如下
sql 复制代码
update t_1 set status = '2' where audit_id = '123' and status='1';

这样保证请求1'进来时,如果请求1已经完成,更新数据行数为0

4. 其他知识

4.1 dubbo默认重试次数

参考 服务重试

4.2 dubbo超时时间

消费者Method>提供者method>消费者Reference>提供者Service>消费者全局配置provider>提供者全局配置consumer

参考在 Provider 端尽量多配置 Consumer 端属性

4.3 幂等性

高并发下如何保证接口的幂等性?

相关推荐
浩腾数字多媒体15 分钟前
如何选择性价比高的地面互动公司?
面试
code_slave(码畜)22 分钟前
微服务架构落地:基础服务 —— 报表服务(上篇:定位、边界与整体架构)
java·spring boot·spring cloud·微服务·架构
不灭的黄金瞳12326 分钟前
Java实现简易图书管理系统
java·intellij-idea
重生之小比特26 分钟前
【C++进阶】02 Linux基本指令
java·数据库·c++
打工仔折腾 AI29 分钟前
从零写一个CAD 04:中键拖动平移,抓住一个点让它一直待在鼠标底下
人工智能·后端·python·性能优化·计算机外设·ai agent 实战
Wang's Blog33 分钟前
Java 项目实战: 外卖平台优化-Nginx常用命令与环境变量配置
java·网络·nginx
sp42a35 分钟前
Java 加解密组件再设计
java
FYKJ_201036 分钟前
springboot家政服务平台66766-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·mysql·spark·课程设计
caoerzhong37 分钟前
开源 WMS 合规交付实务:JeeWMS 仓库管理系统在 GPL-3.0 下的源码台账与交付清单
java·开源
YangYang9YangYan1 小时前
2027 秋招|大数据管理与应用 企业数字化岗位面试高频问题拆解与求职准备
面试·职场和发展