java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction問題
1.問題描述
執行了幾條update語句之后的,再執行其他的update語句,后台就報如下錯誤:
<-- java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4120) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4052) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2503) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2664) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2794) at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2458) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2375) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2359) at com.trs.components.wcm.publish.element.PublishContentDocumentImpl.setPublishTimeAndURL(PublishContentDocumentImpl.java:851) at com.trs.components.common.publish.domain.publisher.PageGenerator.updateContentPublishTime(PageGenerator.java:236) at com.trs.components.common.publish.domain.publisher.PageGenerator.generateDetail(PageGenerator.java:216) at com.trs.components.common.publish.domain.taskdispatch.PageTaskWorker.executeTask(PageTaskWorker.java:278) at com.trs.components.common.publish.domain.taskdispatch.PageTaskWorker.run(PageTaskWorker.java:153) at com.trs.components.common.publish.domain.taskdispatch.ThreadPool$Worker.run(ThreadPool.java:56)
2.問題分析:
2.1 鎖等待超時。是當前事務在等待其它事務釋放鎖資源造成的。可以找出鎖資源競爭的表和語句,優化你的SQL,創建索引等,如果還是不行,可以適當減少並發線程數。
2.2 你的事務在等待給某個表加鎖時超時了,估計是表正被另的進程鎖住一直沒有釋放。可以用 SHOW INNODB STATUS/G; 看一下鎖的情況。
3.問題解決
在使用mysql運行某些語句時,會因數據量太大而導致死鎖,沒有反映。這個時候,就需要kill掉某個正在消耗資源的query語句即可, KILL命令的語法格式如下:
KILL [CONNECTION | QUERY] thread_id
每個與mysqld的連接都在一個獨立的線程里運行,您可以使用SHOW PROCESSLIST語句查看哪些線程正在運行,並使用KILL thread_id語句終止一個線程。
KILL允許自選的CONNECTION或QUERY修改符:KILL CONNECTION與不含修改符的KILL一樣:它會終止與給定的thread_id有關的連接。KILL QUERY會終止連接當前正在執行的語句,但是會保持連接的原狀。
如果您擁有PROCESS權限,則您可以查看所有線程。如果您擁有超級管理員權限,您可以終止所有線程和語句。否則,您只能查看和終止您自己的線程和語句。您也可以使用mysqladmin processlist和mysqladmin kill命令來檢查和終止線程。
首先登錄mysql,然后使用: show processlist; 查看當前mysql中各個線程狀態。
mysql> show processlist;
+---------+------+-------------------+--------------------+---------+-------+-------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+---------+------+-------------------+--------------------+---------+-------+-------+------------------+
| 3205081 | root | 172.19.2.8:50317 | ******** | Sleep | 16485 | | NULL |
| 3205088 | root | 172.19.2.8:50321 | ******** | Sleep | 8170 | | NULL |
| 3205099 | root | 172.19.2.8:50324 | ******** | Sleep | 6123 | | NULL |
| 3205128 | root | 172.19.2.8:50330 | ******** | Sleep | 16254 | | NULL |
| 3205172 | root | 172.19.2.8:50354 | ******** | Sleep | 2723 | | NULL |
| 3205296 | root | 172.19.2.8:50396 | ******** | Sleep | 3804 | | NULL |
| 3210074 | root | 172.19.2.8:50842 | ******** | Sleep | 2582 | | NULL |
| 3210353 | root | 172.19.2.8:51064 | information_schema | Sleep | 3516 | | NULL |
| 3210354 | root | 172.19.2.8:51066 | information_schema | Sleep | 3569 | | NULL |
| 3210630 | root | 172.19.2.12:61845 | ******** | Query | 0 | init | show processlist |
+---------+------+-------------------+--------------------+---------+-------+-------+------------------+
10 rows in set (0.00 sec)
以上顯示出當前正在執行的sql語句列表,找到消耗資源最大的那條語句對應的id.
然后運行kill命令,命令格式如下:
mysql> kill 3205081; Query OK, 0 rows affected (0.00 sec) mysql> kill 3205088; Query OK, 0 rows affected (0.00 sec) mysql> kill 3205099; Query OK, 0 rows affected (0.01 sec) mysql> kill 3205128; Query OK, 0 rows affected (0.00 sec) mysql> kill 3205172 ; Query OK, 0 rows affected (0.00 sec) mysql> kill 3205296; Query OK, 0 rows affected (0.00 sec) mysql> kill 3210074; Query OK, 0 rows affected (0.00 sec)
殺掉即可。