一、问题原因:
数据库重启
或数据库空闲连接超过设置的最大timemout时间
导致数据库会强行断开已有的链接,就会报这个异常。
如果在wait_timeout秒期间内,数据库连接(java.sql.Connection)一直处于等待状态,mysql就将该连接关闭。这时,你的Java应用的连接池仍然合法地持有该连接的引用。当用该连接来进行数据库操作时,就会产生上述错误。一般mysql自身连接的等待时间(wait_timeout)缺省为8小时,或者通过命令参数查看
二、解决办法
1、重启服务器
重启服务器,数据库连接池就会重新初始化, 重新获取和数据库的有效连接
2、连接池配置
1)数据库连接池增加探活配置(推荐这种方式
)
为了避免空闲时间过长超过最大空闲时间而被断开,我们在配置数据库连接池的时候需要做一些检查连接有效性的配置,不同连接池可能不同。
以druid为例相关配置,更多配置参考官网:[配置]
(https://github.com/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E5%88%97%E8%A1%A8)
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:
first: #数据源1
url: jdbc:mysql://XXXX:3306/test?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false
username: test
password: 282s661234567879WWUr4gS
initial-size: 10
max-active: 200
min-idle: 10
max-wait: 60000
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
second: #数据源2
url: jdbc:mysql://XXXX:3306/test?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false
username: test
password: 282s661234567879WWUr4gS
initial-size: 10
max-active: 200
min-idle: 10
max-wait: 60000
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
其中timeBetweenEvictionRunsMillis需要小于mysql的wait_timeout。
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
2)增大数据库默认的超时等待时间(wait_timeout)
之前的文章《MYSQL三大日志及事务隔离级别》(//www.greatytc.com/p/f558d047876d)中讲过两个参数:
interactive_timeout
:服务器关闭交互式连接前等待活动的秒数。(eg:客户端连接交互式连接)
wait_timeout
:服务器关闭非交互连接之前等待活动的秒数。(eg:jdbc连接)
需要修改global的interactive_timeout参数,wait_timeout也会跟着改,可以真正调整超时时间。
Windows下在%MySQL HOME%/bin下有mysql.ini配置文件,需修改配置文件。
linux的服务器上的mysql:
set global interactive_timeout=31536000;(wait_timeout最大为31536000即1年)
注:如果太大,可能导致连接数较多,引起性能下降。
3)JDBC配置Mysql连接URL重连机制
jdbc:mysql://localhost:3306/test?user=root&password=&autoReconnect=true