1 问题

  愉快的星期六,需要接到电话,说系统崩了

  一看日志,发现所以请求全部拿不到数据库链接,等待超时报错,啥都不说,先重启服务器和服务器,恢复正常

  

2 查找原因

1)首先定位到第一个错误,如下

  这个错误是11:10

### Cause: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction

  这里要去操作表1,等待数据库锁,一直获取不到,超时了,这就非常令我困惑了,到底是哪里给它锁住了,先不去找原因,等会再找

  继续往下面查,发现多个这个错误,每10分钟出现一次,一直到12:20(因为这里是一个定时任务(就叫任务1),10分钟会执行一次)

 

2)再往下查,出现我们要找的错误,也就是数据库连接池

  这个错误的时间是12:24  

com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60000, active 24, maxActive 24, creating 0

  然后后面所有请求全部拿不到数据集链接了,全部报的上面这个错误

 

3 分析

  猜测是定时任务1出的问题,但是一想想又不对。任务1全部抛出异常了,不会占用数据库链接的。

  那么肯定就是那个占着表1的锁的那里出的问题。

  于是去找哪些地方有操作表1,发现有四五处地方。

  一一排除后,定位到一个方法里面存在问题。这个方法(就叫方法1)里面都有去请求一个第三方的服务,但是没有设置请求和读取超时时间。

  那么久很有可能是这个第三方服务卡住了,导致进入方法1的线程卡住了,一直占用着锁。

  为了验证猜测,使用postman去调用这个第三方服务,发现可以调用,瞬间懵逼。不信邪,又尝试了几次。果然出现长时间不响应。

  那么问题又来了,一个请求进到方法1,方法1获取到表1的锁,在调用第三方服务这里卡住。下一个请求进来方法1这里,它应该也会因为获取不到表1的锁而超时啊,不可能会一直不停的占用数据库连接导致没有连接可用啊。

  去查日志,果然方法1所在的请求只被请求了一次。也就是说它虽然占着表1的锁,但是没有大量占用数据库连接

  那么只有可能是这个第三方服务在其它地方被调用导致数据库连接被占用。于是去找,还有两个地方调用了这个第三方服务。于是去查日志,果然在11:10到12:24之间,这两个方法被调用多次。

  由于这两个方法在调用这第三方服务之前还没有开始操作数据库,所以这两个方法没有占用数据库表锁,不影响数据库的操作。但是由于一直等待这个第三方服务的相应,导致数据库连接被占用。

  到这里,找到了原因。首先,臭骂一顿没有设置超时时间的小伙子,赶紧又把超时时间设置上。

  

  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/920634.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!