背景

最近做的一个JavaWeb项目,持久层用SpringJDBC+DBCP+MySQL。一开始只配置了DBCP的一些常用参数,没有注意对空闲连接的检查和回收。项目部署在tomcat后,刚开始使用没用问题。第二天再试图登录时,发生了报错:

HTTP Status 500 - Request processing failed; nested exception is org.springframework.dao.RecoverableDataAccessException: PreparedStatementCallback; SQL [select * from users where username = ? and password = ?]; The last packet successfully received from the server was 82,664,635 milliseconds ago. The last packet sent successfully to the server was 82,664,635 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.; nested exception is com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 82,664,635 milliseconds ago. The last packet sent successfully to the server was 82,664,635 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.

可以看到,报错信息提示上次交互已经是82664635ms前,超过了MySQL server配置的'wait_timeout'(默认是8小时),所以该连接已经被MySQL回收了,但DBCP不知道连接已被回收,依然试图执行操作,引发了异常。报错信息提示可以修改wait_timeout或者添加autoReconnect=true。
(备注:mysql5以上的,设置autoReconnect=true 是无效的 只有4.x版本,起作用)

解决办法

  1. 修改MySQL设置(不推荐)
    修改mysql安装目录下的配置文件 my.ini文件(如果没有此文件,复制“my-default.ini”文件,生成“复件 my-default.ini”文件。将“复件 my-default.ini”文件重命名成“my.ini” ),在文件中设置:
wait_timeout=31536000
interactive_timeout=31536000

这两个参数的默认值是8小时(60608=28800)。 注意:wait_timeout的最大值只允许2147483 (24天左右)
也可以用MySQL命令进行修改

show variables like "%timeout%"
set interactive_timeout=31536000
set wait_timeout=31536000

修改wait_timeout

这种办法治标不治本。

2.减少连接池内连接的生存周期,使之小于上一项中所设置的wait_timeout 的值。
也就是说,让已经断开的空闲连接没有机会被使用,提前被回收。
以C3P0配置为例:

 <bean id="dataSource"  class="com.mchange.v2.c3p0.ComboPooledDataSource">      <property name="maxIdleTime"value="1800"/>  <!--other properties -->  </bean>

DBCP中配置minEvictableIdleTimeMillis即可。
3.配置连接池
定期使用连接池内的连接,使得它们不会因为闲置超时而被 MySQL 断开。并且每次使用连接前检查连接是否可用,定期回收空闲的连接。
修改 c3p0 的配置文件,在 Spring 的配置文件中设置:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">  <property name="preferredTestQuery" value="SELECT 1"/>  <property name="idleConnectionTestPeriod" value="18000"/>  <property name="testConnectionOnCheckout" value="true"/>
</bean>

DBCP连接池的配置:

<Resource name="jdbc/TestDB"  JNDI数据源的name
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver" JDBC驱动类
url=""
username="" 访问数据库用户名
password="" 访问数据库的密码
maxActive="80" 最大活动连接
initialSize="10"  初始化连接
maxIdle="60"   最大空闲连接
minIdle="10"   最小空闲连接
maxWait="3000" 从池中取连接的最大等待时间,单位ms.
validationQuery = "SELECT 1"  验证使用的SQL语句
testWhileIdle = "true"      指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除.
testOnBorrow = "false"   借出连接时不要测试,否则很影响性能
timeBetweenEvictionRunsMillis = "30000"  每30秒运行一次空闲连接回收器
minEvictableIdleTimeMillis = "1800000"  池中的连接空闲30分钟后被回收
numTestsPerEvictionRun="3" 在每次空闲连接回收器线程(如果有)运行时检查的连接数量
removeAbandoned="true"  连接泄漏回收参数,当可用连接数少于3个时才执行
removeAbandonedTimeout="180"  连接泄漏回收参数,180秒,泄露的连接可以被删除的超时值
/>

DBCP官方配置文档:http://commons.apache.org/proper/commons-dbcp/configuration.html

其他参数就不多说了,针对连接池失效的几个重要参数做下说明。
1、testOnReturn,testOnBorrow这两个参数为true,表示会在每次请求之前和之后进行连接池测试,如果连接失效,就会将这条连接对象销毁,创建一个新的连接对象,但是本次数据库操作也就失败了。对于读操作可能没什么问题,再请求一次就行了,但对于充值、定时任务等重要写操作来说还不够完美。(PS:使用这两个参数,一定要配置validationQuery参数,这样才会生效。)
2、为了解决以上问题,保证每次操作都有正常的连接池使用,我们来了解一下testWhileIdle参数。这个参数为true时候,表示空闲时是进行验证,检查对象是否有效。然后minEvictableIdleTimeMillis配合timeBetweenEvictionRunsMillis,每过timeBetweenEvictionRunsMillis秒对连接池进行一次检测,将对象闲置时间超过minEvictableIdleTimeMillis秒的对象进行销毁,创建新的对象来取代。这样就能保证时刻都有正常的连接池对象存在。

C3P0的配置标准:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">   <property name="driverClass"><value>oracle.jdbc.driver.OracleDriver</value></property>   <property name="jdbcUrl"><value>jdbc:oracle:thin:@localhost:1521:Test</value></property>   <property name="user"><value>Kay</value></property>   <property name="password"><value>root</value></property>   <!--连接池中保留的最小连接数。-->   <property name="minPoolSize" value="10" />   <!--连接池中保留的最大连接数。Default: 15 -->   <property name="maxPoolSize" value="100" />   <!--最大空闲时间,1800秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->   <property name="maxIdleTime" value="1800" />   <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->   <property name="acquireIncrement" value="3" />   <property name="maxStatements" value="1000" />   <property name="initialPoolSize" value="10" />   <!--每60秒检查所有连接池中的空闲连接。Default: 0 -->   <property name="idleConnectionTestPeriod" value="60" />   <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->   <property name="acquireRetryAttempts" value="30" />   <property name="breakAfterAcquireFailure" value="true" />   <property name="testConnectionOnCheckout" value="false" />
</bean>

参考

关于MySQL的wait_timeout连接超时问题报错解决方案

作者:Jarkata
链接:https://www.jianshu.com/p/048974470bf3
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

解决MySQL8小时自动断开连接的问题(DBCP配置)相关推荐

  1. 客户端连接mysql 自动断开_MySql连接空闲8小时自动断开的原因及连接池配置方法...

    数据库连接超时时间查询 非交互式超时时间,如 JDBC 程序 show global variables like 'wait_timeout'; 交互式超时时间,如数据库工具 show global ...

  2. win7怎么连接不上宽带连接服务器未响应,win7宽带自动断开连接怎么办 win7宽带连接不上的快速解决方法...

    近日很多使用wn7系统的用户出现宽带自动断开连接的情况,大家知道该怎么解决吗?其实这种情况小编也遇到过,下面就为大家分享下小编遇到宽带自动断开连接的解决方法吧!大家如果没有其他的方法部分参照下面的步骤 ...

  3. 【SSH】SSH自动断开连接的原因和解决办法|SSH保持长连接方法

    目录 原因 解决方法 即看即用 方法1:手工修改 方法2:shell命令行修改 详细说明 REMOTE HOST IDENTIFICATION HAS CHANGED问题解决 原因 用putty/Se ...

  4. 云服务器自动断开连接的解决办法

    使用smarTTY连接腾讯云服务器一会不用就会自动断开连接,解决方法如下: 1. 找到sshd_config配置文件 vi /etc/ssh/sshd_config 使用vi打开进行编辑,在文件中找到 ...

  5. 腾讯云服务器自动断开连接的解决办法

    腾讯云服务器自动断开连接的解决办法 1.找到sshd_config配置文件 打开并进行编辑,输入命令: vim /etc/ssh/sshd_config 在此文件中找到以下配置项: # ClientA ...

  6. dbcp连接mysql,8小时会自动断开连接

    为什么80%的码农都做不了架构师?>>>    最近自己做一个项目用到dbcp连接mysql,开始时很正常,可是第二天再访问服务时就出问题了,mysql连接关闭了. mysql在空闲 ...

  7. oracle多久断开连接,Oracle自动断开连接

    ORACLE自动断开数据库连接解决办法 最近,有客户提出在系统的应用中出现数据库频繁自动断开连接(每10分钟)的异常现象,通过查找学习,找到如下两种解决方法.供大家参考. 方法一.直接修改资源配置文件 ...

  8. Linux的SSH登录超时自动断开连接设置

    关于ssh登录超时断开连接的设置有两个方面可以设置 1.修改sshd服务的配置文件sshd_config的内容 #ClientAliveInterval 0   指定了服务器向客户端请求消息的时间间隔 ...

  9. 给websocket加入心跳包防止自动断开连接

    var userId = $("#userId").val(); var lockReconnect = false; //避免ws重复连接 var ws = null; //判断 ...

最新文章

  1. 从工程中删除Cocoapods
  2. 怎样新建Oracle数据库
  3. android7.1增加一个开机自启动的bin应用遇到的权限问题
  4. Windows Server 2012正式版RDS系列⑥
  5. SuperSocket源码解析之开篇 (转)
  6. HDU 5131 Song Jiang's rank list
  7. Dotnet Core使用特定的SDKRuntime版本
  8. Smaug Coverage
  9. 服务器宕机自动dns,有哪些同时支持智能解析和宕机自动切换的DNS服务?
  10. 一串字符串转换为ascii_将ASCII字符串(char [])转换为C中的BYTE数组
  11. 20165302 学习基础和C语言基础调查
  12. ansys电力变压器模型_最佳变压器模型的超参数优化
  13. html go语言,Go 语言基础语法
  14. 立体栅格地图_高精地图之3D栅格地图的应用
  15. 求职经历,三轮技术面 +HR 面,面试也不过如此
  16. SQL AlawaysOn 之三:SQL服务器加入域
  17. 折腾了一把 JAX-WS, SOA Java EE 5 (part 1 of 3)
  18. Linux 内核启动过程--head.S(arch/xxx/kernel下的)
  19. PMP备考-错题集(第6版)
  20. Qt使用多核(jom)加快编译速度

热门文章

  1. [转]最常用的15大Eclipse开发快捷键技巧
  2. iOS常用的存储方式介绍
  3. c#中关于delegate、委托、事件之间的联系、关系
  4. NO.55 网页中压缩的问题
  5. 收藏:PCWorld:火狐浏览器已宣告死亡
  6. 二分答案——木材加工(洛谷 P2440)
  7. et z201 php扩展,ET z201 时间型(Time)
  8. 高中职业学校计算机专业题,职业高中高考计算机专业试题3.doc
  9. DBA遇到问题时的30 个反应,你是哪一种?
  10. 快速掌握:大型分布式系统中的缓存架构