Deadlock found when trying to get lock(死鎖)問題解決
阿新 • • 發佈:2018-12-07
今天壓測使用者中心的登入介面。發現這個介面在併發下幾乎不可用,錯誤率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的更新操作很容易死鎖。
刪除外來鍵後,解決問題。