情景再現:
頁面點擊插入數據操作無反應
問題追溯:
查看日志,sql執行語句輸出,sql語句無錯,報異常Lock wait timeout exceeded; try restarting transaction
解決問題:
直接數據庫執行sql語句,長時間無反應,其他數據行插入成功,外鍵索引列為特定值時插入不成功,判斷該處有鎖未釋放
1:查看當前的事務
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
發現有一個事物處於運行中狀態,trx_mysql_thread_id 進程id為567843
2:查看當前鎖定的事務
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
無事物被鎖
3:查看當前等鎖的事務
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
無事物等待鎖
查出死鎖進程:SHOW PROCESSLIST
進程id為567843的進程運行時長Time50000多秒,一直在運行
殺掉進程 KILL 567843;
該事物結束。重新運行,成功插入
總結:
程序運行到插入數據的函數時,開啟了事物,執行了sql,本來應該commit事物的,由於未知原因未提交,導致事物因為一直在等待提交命令而阻塞。當前事物鎖定了外鍵值一直未釋放,導致后續該外鍵值得數據因為一直等待鎖釋放而執行超時。
項目設置的事物超時時間是默認的-1.如果執行長時間dql事物可設置過期時間,超時會自動回滾
Spring事務超時 = 事務開始時到最后一個Statement創建時時間 + 最后一個Statement的執行時超時時間(即其queryTimeout)。
即事物開始到sql執行結束的時間,sql執行后即使阻塞也不會觸發事物的超時自動回滾