记一次行锁bug

问题描述

前端调用我系统的A接口,A接口里面又去调用了另一个系统的B接口,而B接口回来调用了我系统的C接口。
在我的A和C接口方法上都开启了事务,并且A和C接口都对同一条记录做了写操作,A的写操作在调用B接口之前。

现象

由于这个问题导致我的接口调用出现了超时,但是实际操作是成功了的。

排查

因为另外一个系统地同事告诉我,调用C接口超时了,所以我一开始并没有去看A接口。
C接口实际只有两个操作:一,到数据库里取出这条记录;二,对记录进行了回写。通过查看日志,发现前面的读操作很快,只有几毫秒,但是回写却占用了将近五秒。不相信这么慢,就去看了下数据库,只有一百多条记录,但是问题可以复现的,没有办法,我改成了主键回写,但是没有效果。
之前在主干和测试并没有这个问题,所以理所当然,觉得上线可能就不存在了。结果是上了线,还是很慢。咋办。。。
后来,飞哥帮我线上执行了那条sql,发现很快,只有几十毫秒。那问题到底在哪里呢?
这个时候飞哥提出会不会是发生死锁了,一开始我不太信,但是还是回去检查了下,仔细一看真的是这个问题,两个独立线程的事务,竞争同一条记录的锁,可不就死等了吗?超时,A接口事务结束,C接口事务自然得到执行。

解决

比较糙的法子,我把A接口的事务给去掉了,问题解决

结论

还是要大胆猜想啊,给飞哥点赞。
需要温习下事务方面的知识啦~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章