本人用的是mysql数据库,dbcp连接池,今天在运行项目时,出现数据库连接老中断的现象
解决方案一(推荐)
1.问题解决方案及说明:
https://blog.csdn.net/liuyangvoid/article/details/25975157,出现该现象的原因是:数据库已中断连接池中的连接,但客户端不知道,在连接池中拿到的是已断开与数据库连接的连接
2.validationQuery
SQL查询,用来验证从连接池取出的连接的有效性,在将连接返回给调用者之前.如果指定,则查询及value值必须是一个SQL SELECT查询并且必须返回至少一行记录
3.testOnBorrow
是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个,要使此设置生效,validationQuery参数必须设置为非空字符串https://blog.csdn.net/wangyangzhizhou/article/details/52209336
testOnBorrow和testOnReturn在生产环境一般是不开启的,主要是性能考虑。失效连接主要通过testWhileIdle保证,如果获取到了不可用的数据库连接,一般由应用处理异常
4.testOnReturn
是否在归还到池中前进行检验,要使此设置生效,validationQuery参数必须设置为非空字符串。如果testOnBorrow和testOnReturn设为false,这些连接如果不被其他线程回收的话,它们不会被连接池被废除,也不会重新被创建,占用了连接池的名额,所以一般和removeAbandoned一起使用,清除无效连接
5.testWhileIdle
指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除,要使此设置生效,validationQuery参数必须设置为非空字符串
6.removeAbandoned
是否清除已经超过“removeAbandonedTimout”设置的无效连接。如果值为“true”则超过“removeAbandonedTimout”设置的无效连接将会被清除。设置此属性可以从那些没有合适关闭连接的程序中恢复数据库的连接
7.removeAbandonedTimeout
活动连接的最大空闲时间,单位为秒 超过此时间的连接会被释放到连接池中,针对未被close的活动连接
8.logAbandoned
设置为true,程序在回收连接的同时会打印日志
9.minEvictableIdleTimeMillis
连接池中连接可空闲的时间,单位为毫秒 针对连接池中的连接对象,若连接池的连接数小于最小空闲连接数minIdle,则创建数据库连接,同时检查连接池的连接是否小于maxIdle,是则把刚创建的连接放入连接池中,否则销毁此对象(运行机制参考:https://blog.csdn.net/pq258280920/article/details/17136335)
10.timeBetweenEvictionRunsMillis / minEvictableIdleTimeMillis
每timeBetweenEvictionRunsMillis毫秒秒检查一次连接池中空闲的连接,把空闲时间超过minEvictableIdleTimeMillis毫秒的连接断开,直到连接池中的连接数到minIdle为止
11.numTestsPerEvictionRun
设定在进行后台对象清理时,每次检查几个链接。默认值是3,如果numTestsPerEvictionRun>=0, 则取numTestsPerEvictionRun 和池内的链接数 的较小值 作为每次检测的链接数;如果numTestsPerEvictionRun<0,则每次检查的链接数是检查时池内链接的总数乘以这个值的负倒数再向上取整的结果
12.能让连接池对象每时都正常存在的原因
对象闲置时间超过minEvictableIdleTimeMillis秒的对象进行销毁,创建新的对象来取代
13.minEvictableIdleTimeMillis和removeAbandonedTimeout区别
minEvictableIdleTimeMillis,removeAbandonedTimeout这两个参数针对的连接对象不一 样,minEvictableIdleTimeMillis针对连接池中的连接对象,removeAbandonedTimeout针对未被close的 活动连接
解决方案二
因为mysql默认连接闲置8小时 (8小时内没有进行数据库操作), mysql就会自动断开连接, 要重启tomcat,这样连接数据库的时候加上autoReconnect=true这个参数,即:
jdbc.url=jdbc:mysql://47.104.222.101:3306/jdy_test?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&autoReconnect=true
但在mysql文档上有这样一句话:驱动程序是否应尝试再次建立失效的或死连接?
如果允许,对于在失效或死连接上发出的查询(属于当前事务),驱动程序将抛出异常,但在新事务的连接上发出下一个查询时,将尝试再连接。不推荐使用该特性,这是因为,当应用程序不能恰当处理SQLExceptions时,它会造成与会话状态和数据一致性有关的副作用,设计它的目的仅用于下述情况,即,当你无法配置应用程序来恰当处理因死连接和/或无效连接导致的SQLExceptions时。作为可选方式,可将MySQL服务器变量“wait_timeout”设置为较高的值,而不是默认的8小时。
但是我改为这样并没有发现异常,附一张mysql参数说明:
参数名称 | 参数说明 | 缺省值 | 最低版本要求 |
user | 数据库用户名(用于连接数据库) | 所有版本 | |
password | 用户密码(用于连接数据库) | 所有版本 | |
useUnicode | 是否使用Unicode字符集,如果参数characterEncoding设置为gb2312或gbk,本参数值必须设置为true | false | 1.1g |
characterEncoding | 当useUnicode设置为true时,指定字符编码。比如可设置为gb2312或gbk | false | 1.1g |
autoReconnect | 当数据库连接异常中断时,是否自动重新连接? | false | 1.1 |
autoReconnectForPools | 是否使用针对数据库连接池的重连策略 | false | 3.1.3 |
failOverReadOnly | 自动重连成功后,连接是否设置为只读? | true | 3.0.12 |
解决方案三
开启取或放连接,即将testOnBorrow和testOnReturn改为true
<property name="validationQuery" value="select current_date()"/>
<property name="testOnBorrow" value="true"/>
<property name="testOnReturn" value="true"/>
但是我发现这样如果连接中断后,取连接时会比较慢的。(自己分析可能时间花费在了检测连接是否有效上面了)
解决方案四
网上得知,说是增大mysql的wait_timeout时间,但是我查询,得到的时间实际挺长的啊,默认值是28800,单位是秒,8小时,但是就是不行