Mysql事物鎖等待超時 Lock wait timeout exceeded; try restarting transaction

問題場景
問題出現環境: 
一、在同一事務內前後對同一條數據進行插入和更新操做; 
二、多臺服務器操做同一數據庫; 
三、瞬時出現高並發現象;html

不斷的有一下異常拋出,異常信息:java

org.springframework.dao.CannotAcquireLockException: 
### Error updating database.  Cause: java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction
### The error may involve com.*.dao.mapper.PhoneFlowMapper.updateByPrimaryKeySelective-Inline
### The error occurred while setting parameters
### SQL:-----後面爲SQL語句及堆棧信息-------- 

緣由分析
在高併發的狀況下,Spring事物形成數據庫死鎖,後續操做超時拋出異常。 
Mysql數據庫採用InnoDB模式,默認參數:innodb_lock_wait_timeout設置鎖等待的時間是50s,一旦數據庫鎖超過這個時間就會報錯。spring

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

select * from information_schema.innodb_trx

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

innodb_lock_wait_timeout=500

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

參考信息
一、鎖等待超時。是當前事務在等待其它事務釋放鎖資源形成的。能夠找出鎖資源競爭的表和語句,優化SQL,建立索引等。若是仍是不行,能夠適當減小併發線程數。 
二、事務在等待給某個表加鎖時超時,估計是表正被另的進程鎖住一直沒有釋放。 
能夠用 SHOW INNODB STATUS/G; 看一下鎖的狀況。 
三、搜索解決之道,在管理節點的[ndbd default]區加: 
TransactionDeadLockDetectionTimeOut=10000(設置 爲10秒)默認是1200(1.2秒) 
四、InnoDB會自動的檢測死鎖進行回滾,或者終止死鎖的狀況。mybatis

InnoDB automatically detects transaction deadlocks and rolls back a transaction or transactions to break the deadlock. InnoDB tries to pick small transactions to roll back, where the size of a transaction is determined by the number of rows inserted, updated, or deleted.併發

若是參數innodb_table_locks=1而且autocommit=0時,InnoDB會留意表的死鎖,和MySQL層面的行級鎖。另外,InnoDB不會檢測MySQL的Lock Tables命令和其餘存儲引擎死鎖。你應該設置innodb_lock_wait_timeout來解決這種狀況。 
innodb_lock_wait_timeout是Innodb放棄行級鎖的超時時間。app

參考文章:http://www.51testing.com/html/16/390216-838016.html框架

深刻研究 因爲此項目採用Spring+mybatis框架,事物控制採用「org.springframework.jdbc.datasource.DataSourceTransactionManager」類進行處理。此處還需進行進一步調研Spring實現的機制。 ---------------------  做者:朱智勝  來源:CSDN  原文:https://blog.csdn.net/wo541075754/article/details/50717842  版權聲明:本文爲博主原創文章,轉載請附上博文連接!