天天看點

記一次行鎖bug

問題描述

前端調用我系統的A接口,A接口裡面又去調用了另一個系統的B接口,而B接口回來調用了我系統的C接口。

在我的A和C接口方法上都開啟了事務,并且A和C接口都對同一條記錄做了寫操作,A的寫操作在調用B接口之前。

現象

由于這個問題導緻我的接口調用出現了逾時,但是實際操作是成功了的。

排查

因為另外一個系統地同僚告訴我,調用C接口逾時了,是以我一開始并沒有去看A接口。

C接口實際隻有兩個操作:一,到資料庫裡取出這條記錄;二,對記錄進行了回寫。通過檢視日志,發現前面的讀操作很快,隻有幾毫秒,但是回寫卻占用了将近五秒。不相信這麼慢,就去看了下資料庫,隻有一百多條記錄,但是問題可以複現的,沒有辦法,我改成了主鍵回寫,但是沒有效果。

之前在主幹和測試并沒有這個問題,是以理所當然,覺得上線可能就不存在了。結果是上了線,還是很慢。咋辦。。。

後來,飛哥幫我線上執行了那條sql,發現很快,隻有幾十毫秒。那問題到底在哪裡呢?

這個時候飛哥提出會不會是發生死鎖了,一開始我不太信,但是還是回去檢查了下,仔細一看真的是這個問題,兩個獨立線程的事務,競争同一條記錄的鎖,可不就死等了嗎?逾時,A接口事務結束,C接口事務自然得到執行。

解決

比較糙的法子,我把A接口的事務給去掉了,問題解決

結論

還是要大膽猜想啊,給飛哥點贊。

需要溫習下事務方面的知識啦~