dubbo重试(retry)导致事务重复执行提交

1.背景

公司有个模块最近有新需求,因此有些地方需要改动,而测试同学在测的过程中发现有个地方报了错让我看看,于是我看了一下报错日志,是因为数据库有重复数据,初步推断应该是在写接口导致的数据写入多条。

2.排查过程

​ 我先是把重复数据手动删除,然后尝试复现同事的操作。发现在编辑的时候,接口返回时长特别慢,导致了报错。然后数据库多了一条重复数据,最开始的想法是,是不是在界面的操作中出现了重复点击这个问题,于是我本地连接测试数据库进行调试。

​ 我在controller层和service层都打上了断点,然后重新调用了几次,发现有几次是产生了重复数据的,但是有几次又没有。同事之前写这段代码的时候,不是利用@Transactional注解而是利用的手动在代码中处理事务(代码如下),我在提交事务和回滚事务的地方都打上了断点,发现有时候tx.commit(status)会被断点拦截两次,而有时候tx.commit(status);tx.rollback(status);各会被断点拦截一次,但是controller层的断点却又只被拦截一次,于是我判断这不是来自重复点击的问题,因为如果重复点击,controller层也会被调用两次才对。

事务控制

​ 那会是什么问题呢?我看了一下controller层报错,报错信息如下,这段信息表名,controller层在利用dubbo调用service时,出现了超时的情况,我们超时时长设置的是60s,并且设置了reties=1,即超时重试机制,于是我明白了,应该是controller在调用service出现超时后,重试机制再调用了service一次,导致了service被执行了两次,导致事务重复提交,所以数据库出现了重复数据。

duboo调用超时报错

​ 可是为什么有时候不会出现重复数据呢?我继续打断点寻找,终于,在一次没有出现重复数据时发现了以下报错。就是说在dubbo重试机制执行时,重新开启事务,但是因为前面的事务没有结束,而后面的事务操作的数据跟前一个事务操作的是一样的数据,所以导致第一个事务锁住了表,第二个事务就需要等待第一个事务执行完,但是有时候第一个事务执行的时间过长,导致第二个事务锁超时。这样也就出现了有时会出现重复数据,有时不会。

事务执行超时报错

3. 总结

在使用dubbo的时候,业务逻辑不要超过dubbo设置的超时时长,不然会触发dubbo的重试机制,导致service被重复调用执行

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值