一.概述
工作中遇到了问题,C3P0连接池中连接达到500个,导致再从连接池取连接失败;但是查看mysql的连接数,只有200个;
按我的理解,连接池内维护的就是mysql的连接,要用时直接取,不需要再从数据库创建.
问题最终定位到代码中连接用完没有close,未释放到连接池;
二.疑惑
连接池中的连接没有close返回连接池,达到500个,为什么mysql查看到连接数是200个,不应该也是500个吗?
三.可能的原因
1.c3p0缺少健康检查机制,连接池中连接断开连接失效了但是还在连接池中;这可以解释mysql连接数和连接池连接数不一致问题;但是这种说法加深了我的疑问,代码确实是存在连接未close交还给连接池,在连接池中一直占用,难道连接在连接池中一直占用但是不操作会导致连接从mysql断开,但是池中不会被释放掉,导致垃圾数据?似乎有些道理
2.连接池中的连接和mysql的连接,概念上并不是一个东西;但是这个有悖于连接的定义.
四.最终结论
从目前我的角度来说,我更支持第1种原因,因为质疑连接池中连接和msql的连接的定义,找不到任何依据,毕竟连接池的连接,是调用jdbc的接口获取到的,应该属于同一个东西.
连接池超出连接最大值的解释:c3p0连接池中的连接使用完了没有close释放掉,又没有使用,导致连接池认定该连接被原来的sql占用;新的请求过来,连接池只能又创建新的连接来处理请求,导致连接池连接数量超过最大值;
连接池中连接数量远大于mysql中查到的数据的解释:mysql连接有默认最大空闲时间8小时的设定,连接一直空闲没有被调用,会被mysql数据库自动断开,所以mysql查询到的连接数是200;但是对于连接池来说,自动断开失效的连接,因为没有被close掉,所以连接池认为连接还在使用(其实已经失效),无法被清理出连接池,所以占用了连接池的空间,导致连接数不一致.
目前来说,可以比较完美的解释这个异常现象. 如果后续有遇到dba大神,会沟通下这个理解的正确性...
最后,附上c3p0官方文档地址,里面包含参数定义和解释,以便查阅:
https://www.mchange.com/projects/c3p0/
工具
//使用到的mysql命令
show [full] processlist; //显示所有的连接线程,full可选
show variables like "timeout"; //显示mysql设置中timeout相关的参数
set global interactive_timeout=1800; //设置交互连接断开超时时间为1800秒
set global wait_timeout=1800; //设置非交互连接断开超时时间