try resarting tansaction异常定位解决
问题介绍
今天在搞一套新的环境服务时,一个项目出现了该问题,日志会抛出 try resarting tansaction 的问题,代码都是生产环境正常运行的,下面描述问题的定位思路
业务流程介绍
该业务为充值业务,用户支付宝充值,我方收到支付宝回调开始执行余额变动操作,此操作中使用事务保证完整性。
try resarting tansaction 原因
try resarting tansaction 这个错误是因为在对事务操偶作中的数据进行二次事务操作导致的,如 执行第一条sql时,开启了事务,在事务提交之前,另一个请求开启事务执行第二条sql,就会导致改异常,因为事务对该行进行了行级锁。
update table set money = 1 where id = 10002 and version =1
update table set money = 2 where id = 10002 and version =1
我们可以执行以下sql来进行查看事务状态
select * from information_schema.innodb_lock_waits;
但我这里查出来是空,代表并没有死锁的问题,这就变得迷惑了起来。
细想了一下所有可能性
- 数据库配置事务时间过短导致
因未查询到wait状态的事务,所以和此无关 - 代码出现事务套事务导致
校验过代码,只有一个事物,且其他环境无问题,所以无关。 - 方法重复调用导致
因该方法为支付宝回调,不存在同时调用的情况,但是还去验证了一下,在tomcat的access日志查了一下,竟然重复调用了。
问题结局
支付宝导致,但支付宝不应该存在低级的bug,后面仔细思考了一下,找到了问题根源。
因为是新的环境,所以ip端口都要改变,支付宝异步回调地址忘记了修改,导致回调到之前的服务,服务无法处理改数据就返回错误,一直在重试,当我把支付宝回调改为正确的ip地址后,支付宝就把之前失败的一口气推送了过来,导致该异常。
处理结果比较简单了,slb配置了下秒级相同请求不分发到不同服务器,指向同一服务器,然后接口层做令牌桶限流,确保相同用户不存在并发,解决。