[Mysql+JAVA+druid] 解决java数据库链接失效问题The last packet successfully received from the server was 3 milliseconds ago. The last packet sent successfully to the server was 1 milliseconds ago.错误

 

触发现象

java 数据库设置异常出力 java 数据库连接超时_mariadb


第一次调用报上图错误,第二次恢复正常。

 

引起原因

查询数据库wait_timeout(服务器关闭非交互连接之前等待活动的秒数)

show global variables like “wait_timeout”;

java 数据库设置异常出力 java 数据库连接超时_数据库_02


查询日志日期

java 数据库设置异常出力 java 数据库连接超时_mariadb_03

查询到数据库最大等待时间为1800s,再查看其日志打印间隔,发现程序上次打印日志活动时间为23日早上9点20,但是报错日志时间为24日晚上20:17分,检查日志发现报错时为当天第一次对数据库进行操作。
并检查druid配置发现没有配置异常。

结论:如果jdbc链接与数据库1800秒都没有交互,那么数据库会主动将该次链接断开。但是该链接在数据库连接池中,程序并不知道链接是否已经失效,当程序在调用数据库时,使用该链接发现已经被数据库主动断开失效,所以报出上面的错误。

解决办法:

1.重新调用,重新调用会重新获取数据库链接。
2.testOnBorrow  默认为false
指明是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个.
在durid配置文件加上
test-on-borrow: true
3.在链接加上autoReconnect=true
jdbc:mysql://localhost:3306/test?user=root&password=&useUnicode=true&characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false
4.加大wait_timeout的值

####部分mysql时间参数解释

java 数据库设置异常出力 java 数据库连接超时_java_04


connect_timeout

解释:在获取链接时,等待握手的超时时间,只在登录时有效,登录成功这个参数就不管事了。主要是为了防止网络不佳时应用重连导致连接数涨太快,一般默认即可。

delayed_insert_timeout
解释:这是为MyISAM INSERT DELAY设计的超时参数,在INSERT DELAY中止前等待INSERT语句的时间。

innodb_lock_wait_timeout
手册描述:
解释:事务遇到锁等待时的Query超时时间。跟死锁不一样,InnoDB一旦检测到死锁立刻就会回滚代价小的那个事务,锁等待是没有死锁的情况下一个事务持有另一个事务需要的锁资源,被回滚的肯定是请求锁的那个Query。

innodb_rollback_on_timeout
解释:这个参数关闭或不存在的话遇到超时只回滚事务最后一个Query,打开的话事务遇到超时就回滚整个事务。

interactive_timeout/wait_timeout
解释:一个持续SLEEP状态的线程多久被关闭。线程每次被使用都会被唤醒为activity状态,执行完Query后成为interactive状态,重新开始计时。wait_timeout不同在于只作用于TCP/IP和Socket链接的线程,意义是一样的。

net_read_timeout / net_write_timeout
解释:这个参数只对TCP/IP链接有效,分别是数据库等待接收客户端发送网络包和发送网络包给客户端的超时时间,这是在Activity状态下的线程才有效的参数

slave_net_timeout
解释:这是Slave判断主机是否挂掉的超时设置,在设定时间内依然没有获取到Master的回应就人为Master挂掉了