首页 > 代码库 > 连接池(理论上应该是任意连接池) 、spring方法切入、 mybatis 、 redis等待请求 用了mysql连接的方法阻塞超过8小时导致mysql关闭连接 应用复活后用了已关闭连接而异常

连接池(理论上应该是任意连接池) 、spring方法切入、 mybatis 、 redis等待请求 用了mysql连接的方法阻塞超过8小时导致mysql关闭连接 应用复活后用了已关闭连接而异常

服务进程中的服务方法blpop阻塞在redis队列下(等待请求),  使用方(客户代码)向该队列push请求以促使服务方法在阻塞的代码行继续运行下去。

服务方法使用了mybatis的SqlSessionTemplate, 在进入服务方法时spring为mybatis调用了连接池druid的getConnection,

             假设很久没有请求来,一直阻塞在blpop处,直到mysql的wait_timeout默认8小时到达(导致mysql实际上已经关闭了该连接),  

             而此时处在方法内部, 一旦有请求来,代码从阻塞处继续运行,没有机会促使spring调用一次连接池的getConnection,从而没有机会使得连接池获知该连接已无效,而导致使用了一个无效的连接。

             但下一次再进入服务方法,又正常了,直到再次超过8小时没有请求过来,又这样。

问题简述:使用了mysql连接的方法执行时间超过了8个小时,导致mysql关闭了连接,而方法复活的时候不知道连接已经关闭了。

根结是应用代码的结构不良。

应该改为:  将服务方法分为两个方法:一个等待请求,一个用请求来执行服务逻辑。   等待请求的方法会阻塞,但不需要spring去切入。     执行服务的方法一旦运行不会阻塞(执行所需时间很短),spring对该方法切入了连接池的getConnection。

 

连接池(理论上应该是任意连接池) 、spring方法切入、 mybatis 、 redis等待请求 用了mysql连接的方法阻塞超过8小时导致mysql关闭连接 应用复活后用了已关闭连接而异常