錯誤訊息:
Lock wait timeout exceeded; try restarting transaction
Lock wait timeout exceeded; try restarting transaction
MySQL Lock wait timeout exceeded 是 InnoDB 常見的鎖等待超時錯誤。 當某個 transaction 正在等待資料鎖,但超過 MySQL 設定時間仍無法取得鎖時,就會被強制中斷。
這類問題常見於高併發系統,例如電商訂單、API 更新、後台批次處理等。 本質是「資料鎖競爭」,而不是單純 SQL 錯誤。
一、發生原因
- Transaction 未 commit 或 rollback
- 大量 UPDATE / DELETE 同時執行
- 多請求同時修改同一筆資料
- SQL 未使用 Index 導致鎖範圍過大
- 長時間查詢佔用鎖資源
👉 InnoDB 是 row-level lock,但仍可能因範圍掃描變成大鎖
二、快速檢查問題來源
SHOW PROCESSLIST;
SHOW ENGINE INNODB STATUS;
SELECT * FROM information_schema.innodb_trx;
✔ 用來找出卡住的 transaction 與鎖來源
三、快速修復(暫時解法)
SET GLOBAL innodb_lock_wait_timeout = 120;
⚠️ 這只是延長等待時間,不能解決根本問題
🔧 重啟 MySQL(必要步驟)
systemctl restart mysqld
👉 修改 my.cnf 或 timeout 後,必須重新啟動 mysqld 才會生效。
四、根本解法(最重要)
- 確保 transaction 正確 commit / rollback
- 避免長時間 transaction
- 加 Index 減少掃描範圍
- 拆分大量 UPDATE / DELETE
- 避免多請求同時寫同一資料
✔ 核心重點:縮短鎖持有時間,而不是只提高 timeout
五、SQL 錯誤 vs 正確寫法
-- ❌ 錯誤:鎖整張表 UPDATE orders SET status = 1;
-- ✔ 正確:縮小鎖範圍 UPDATE orders SET status = 1 WHERE id = 100;
👉 沒有 WHERE + 沒有 Index = 高機率鎖爆
延伸閱讀(MySQL 錯誤排除系列(2026)
FAQ 常見問題
MySQL Lock wait timeout exceeded 是什麼?
代表 transaction 等待資料鎖超時,被 MySQL 強制中斷,通常是鎖競爭或未釋放 transaction。
這跟 deadlock 有什麼不同?
deadlock 是互相卡住形成循環等待,timeout 是等待太久被系統強制結束。
調整 timeout 可以解決嗎?
只能暫時緩解問題,無法解決鎖競爭的根本原因。
最常見原因是什麼?
未正確 commit transaction 或大量 UPDATE 同時執行。
如何找出卡住的 SQL?
使用 SHOW ENGINE INNODB STATUS 可以查看鎖與等待資訊。
Index 有幫助嗎?
有,可以減少掃描範圍,降低鎖定資料量。
CodeIgniter 會造成嗎?
如果 transaction 沒有正確關閉,也可能導致鎖累積。
會影響網站嗎?
會,可能導致 API 無回應或訂單失敗。
最佳解法是什麼?
正確設計 transaction + index 優化 + 縮短鎖時間,而不是只調 timeout。
這是 MySQL 錯誤排除系列文章之一,包含記憶體、連線、鎖定三大類問題。
