java.sql.SQLException: Lock wait timeout exceeded

        这个项目是我接手某位大仙的,真想把ta供起来,然而这个people我从来没见过也不知道是谁,可能老师知道,不对,他一定知道!(只能从现有网页的最底下logo看到是广州某公司,非常想给它删掉换成我的个人签名。)这也就加大了我的编程难度,无法随意改动大仙的代码,时刻要揣摩大仙的编码意图。以前不知道从哪里看的或者听得一句话,大意就是每个程序猿写出的代码毕竟有ta的意图,不要随意去批评别人的代码,我就怕自己的水平有限误解了大仙的代码,所以一边代码一边小心翼翼的在心里骂ta,只有我再三确定ta的某些代码跟屎一样,我才会大声骂出来。代码基本没有注释我就不说了,每个entity一个Dao我就不说了,错误正常都向用户返回成功的提示我也特么也不说了,数据库表结构设计的我真是第一次见到,理解大仙的代码和思路,三个字:难!难!难!当然肯定有可学习之处,应该是在套其所在神级公司的现有框架,不过以我得水平,觉得好像把spring的有些东西实现了一下,但是这些代码和业务代码高耦合。这个项目本身最大的难点在于数据种类多,复杂,基本都是医学用词,摆在我面前的除了这个,还有大仙留下的一个个坑T T。

       一下子没忍住, 好了,进入正题~,项目中用到的技术是html+ajax+servelet+ibatis,这个我没办改变,不可能去重构代码。

       先说我我的解决方法:找到锁住的线程然后kill掉。

mysql> kill thread id;

       下面我们分析一下。

       show processlist查看所有运行的线程,发现所有线程的状态都是sleep,查了下sleep状态大意就是未释放资源,线程正在等待客户端发送新的请求。可能会有疑问为什么没有locked状态,查了下innodb的行锁并不会体现在线程状态中,这样就能解释通明明是锁等待为什么状态是sleep。

mysql> show full processlist;
+------+------+---------------------+----------+---------+-------+-------+-----------------------+
| Id   | User | Host                | db       | Command | Time  | State | Info                  |
+------+------+---------------------+----------+---------+-------+-------+-----------------------+
| 1172 | root | 112.124.64.64:43083 | eye      | Sleep   | 12384 |       | NULL                  |
| 1179 | root | 112.124.64.64:43086 | eye      | Sleep   |   596 |       | NULL                  |
| 1181 | root | 112.124.64.64:43087 | eye      | Sleep   | 12467 |       | NULL                  |
| 1182 | root | 112.124.64.64:43088 | eye      | Sleep   |   149 |       | NULL                  |
| 1183 | root | 112.124.64.64:43089 | eye      | Sleep   |   612 |       | NULL                  |
| 1184 | root | 112.124.64.64:43090 | eye      | Sleep   |    39 |       | NULL                  |
| 1197 | root | 112.124.64.64:43092 | eye      | Sleep   |   148 |       | NULL                  |
| 1198 | root | 112.124.64.64:43093 | eye      | Sleep   |  5415 |       | NULL                  |
| 1200 | root | 112.124.64.64:43095 | eye      | Sleep   |   581 |       | NULL                  |
| 1289 | root | 58.249.112.63:5657  | eye      | Sleep   |  1496 |       | NULL                  |
| 1325 | root | localhost           | NULL     | Query   |     0 | NULL  | show full processlist |
+------+------+---------------------+----------+---------+-------+-------+-----------------------+

       看information_schema库中的INNODB_TRX表发现有几条记录,时间和用户反馈的时间是对上号的,id号在上结果中也有显示,表列太多,截图没截全:

java.sql.SQLException: Lock wait timeout exceeded_第1张图片

       show engine innodb status发现有以下几行:

---TRANSACTION 17E34B, ACTIVE 3296 sec
2 lock struct(s), heap size 376, 0 row lock(s), undo log entries 15
MySQL thread id 1196, OS thread handle 0x7f1f0759d700, query id 140864 112.124.64.64 root
Trx read view will not see trx with id >= 17E34C, sees < 17DFA9
---TRANSACTION 17E11F, ACTIVE 6222 sec
10 lock struct(s), heap size 3112, 9 row lock(s), undo log entries 11
MySQL thread id 1199, OS thread handle 0x7f1f07458700, query id 140844 112.124.64.64 root
Trx read view will not see trx with id >= 17E120, sees < 17DFA9
---TRANSACTION 17DFAA, ACTIVE 11653 sec
2 lock struct(s), heap size 376, 0 row lock(s), undo log entries 15
MySQL thread id 1178, OS thread handle 0x7f1f0af75700, query id 133760 112.124.64.64 root
Trx read view will not see trx with id >= 17DFAB, sees < 17DFA7
---TRANSACTION 17DFA9, ACTIVE 11655 sec
3 lock struct(s), heap size 376, 1 row lock(s), undo log entries 15
MySQL thread id 1177, OS thread handle 0x7f1f1b682700, query id 133743 112.124.64.64 root
Trx read view will not see trx with id >= 17DFAA, sees < 17DFA7
......
ROW OPERATIONS
--------------
0 queries inside InnoDB, 0 queries in queue
5 read views open inside InnoDB
Main thread process no. 27675, id 139771259049728, state: waiting for server activity
Number of rows inserted 3158, updated 834, deleted 113, read 34640784364
0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s

       不是特别理解"MySQL thread id 1196, OS thread handle 0x7f1f0759d700, query id 140864 112.124.64.64 root

Trx read view will not see trx with id >= 17E34C, sees < 17DFA9",Trx read view will not see trx是指事务找不到还是connection 找不到了还是咋的?"undo log entries 15"的意思是15条没有insert进去,还是回滚操作没有回滚回来?ROW OPERATIONS下面的

state: waiting for server activity
Number of rows inserted 3158, updated 834, deleted 113, read 34640784364

怎么从这个中找到有用信息,让我知道哪些语句操纵哪些表哪些行时出了问题,3158,834这些数字能给人什么提示?希望以后有机会让大神看到这篇博客帮我解惑。

       查找过程中看到某博客mysql 执行状态分析 show processlist中一段“实战范例:因前端数据输出时(特别是输出到用户终端)未及时关闭数据库连接,导致因网络连接速度产生大量sleep连接,在网速出现异常时,数据库too many connections挂死。简单解读,数据查询和执行通常只需要不到0.01秒,而网络输出通常需要1秒左右甚至更长,原本数据连接在0.01秒即可释放,但是因为前端程序未执行close操作,直接输出结果,那么在结果未展现在用户桌面前,该数据库连接一直维持在sleep状态!”这段话说“因为前端程序未执行close操作,直接输出结果,那么在结果未展现在用户桌面前,该数据库连接一直维持在sleep状态”,我不太懂,为什么等到结果展现给用户后才close操作,一般不都是把数据查上来(这个时候链接是释放了的)才在service层处理,之后才通过control层返回给浏览器呈现。

       我觉得这次MySQL出现这个问题很可能因为网络原因,用户等不急返回结果,关掉了插入数据操作的modal框,又点击添加,打开一个新的模态框操作同一患者的信息导致的。但是我的service层的每次操作是手动开启手动关闭事务的,看了ibatis源码,事务完成后会关闭链接session,为什么还会出现长时间等待?而且好像对之后的其他行数据操作也产生了影响,其他事务操作的是不同行数据,难道因为查询时需要全表扫描导致所有事务等死了?

public void endTransaction() throws SQLException {
    try {
      getLocalSqlMapSession().endTransaction();
    } finally {
      getLocalSqlMapSession().close();
    }
  }

       世行无难事,只怕有心人,以上的所有疑问总有一天肯定会全部清除的,之后也会记录下供大家学习~

你可能感兴趣的:(mysql,ibatis,INNODB_TRX)