mysql事物鎖等待超時,報錯 Lock wait timeout exceeded; try restarting transaction

 

問題場景

問題出現環境: 

一、在同一事務內前後對同一條數據進行插入和更新操做; 

二、多臺服務器操做同一數據庫; 

異常信息:mysql

_mysql_exceptions.OperationalError: (1205, 'Lock wait timeout exceeded; try restarting transaction')


 

緣由分析

在高併發的狀況下形成數據庫死鎖,後續操做超時拋出異常。 

Mysql數據庫採用InnoDB模式,默認參數:innodb_lock_wait_timeout設置鎖等待的時間是50s,一旦數據庫鎖超過這個時間就會報錯。
 sql

解決方案

一、經過下面語句查找到爲提交事務的數據,kill掉此線程便可。
 數據庫

select * from information_schema.innodb_trx



二、增長鎖等待時間,即增大下面配置項參數值,單位爲秒(s)
 服務器

innodb_lock_wait_timeout=500



三、優化存儲過程,事務避免過長時間的等待。併發

 

 

擴展閱讀:

在InnoDB Plugin以前,通常經過show full processlist(很難發現被鎖的行記錄問題所在)和show engine innodb status命令查看當前的數據庫請求,而後再判斷當前事務中鎖的狀況。隨着mysql的發展,已經提供更加便捷的方法來監控數據庫中的鎖等待現象了。高併發

在information_schema下面有三張表:INNODB_TRX、INNODB_LOCKS、INNODB_LOCK_WAITS(解決問題方法),經過這三張表,能夠更簡單地監控當前的事務並分析可能存在的問題。優化

比較經常使用的列:spa

trx_id:InnoDB存儲引擎內部惟一的事物ID
trx_status:當前事務的狀態
trx_status:事務的開始時間
trx_requested_lock_id:等待事務的鎖ID
trx_wait_started:事務等待的開始時間
trx_weight:事務的權重,反應一個事務修改和鎖定的行數,當發現死鎖須要回滾時,權重越小的值被回滾
trx_mysql_thread_id:MySQL中的進程ID,與show processlist中的ID值相對應
trx_query:事務運行的SQL語句線程

例如工做中遇到了一條表記錄,select * from car for update 或者是修改某個字段的值,就報錯:Lock wait timeout exceeded; try restarting transactionrest

解決方法是直接查詢上面說的三個表,而後kill 進程ID;  另外從根本上從業務邏輯代碼優化對數據庫的操做,以前也遇到過此類狀況,好比剛剛修改完這條記錄,接着再次修改,也會報此錯誤,從代碼和業務層面儘可能避免開來。