1. 程式人生 > >Deadlock found when trying to get lock(死鎖)問題解決

Deadlock found when trying to get lock(死鎖)問題解決

今天壓測使用者中心的登入介面。發現這個介面在併發下幾乎不可用,錯誤率70%。

檢視後臺日誌全是:

登入接口出現死鎖了。

看了下程式碼,登入中做了更新使用者登入時間,插入使用者log。查詢資料庫,發行使用者更新和插入log都會lock wait

判斷可能是在壓測同一個使用者登入時,某個請求中的事務讀取到了另一個請求裡事務未提交的資料。從而需要等待之前的事務提交。(幻讀)

然後將事務隔離機制改成SERIALIZABLE。

@Transactional(isolation= Isolation.SERIALIZABLE)。

然而並不能解決問題。

後來發現問題出現在記錄使用者日誌上

save(user)後,user物件是持久態,然後把持久態的user塞到userlog物件裡

雖然這裡沒配置@cascade,但是如果物件是持久態的話,會預設級聯更新。

所以在後續我執行save(userlog)時,有對這個user update了一遍。照成死鎖。

 

然後我去除了manyToOne的依賴,改成ID。

結果fuck,問題依然存在!

 

最後看到一篇文章:

https://www.percona.com/blog/2006/12/12/innodb-locking-and-foreign-keys/

才發現罪魁或者是外來鍵,userLog表有外來鍵。

當插入一條userLog時,會把關聯的user資料給鎖了,然後對這個user的更新操作很容易死鎖。

刪除外來鍵後,解決問題。