监控mysql连接超时_解决MySql数据库连接超时问题

在Mysql的默认设置中,如果一个数据库连接超过8小时没有使用(闲置8小时,即28800s),mysql server将主动断开这条连接。

e94d3357c7ed90d85f9aa8df30feed51.png

在运维监控系统中,程序会报如下异常:

org.springframework.orm.hibernate3.HibernateJdbcException: JDBC exception on Hibernate data access; nested exception is org.hibernate.exception.GenericJDBCException: could not inspect JDBC autocommit mode

底层错误日志:

[130925-102435-381][ERROR][ActionQueue:afterTransactionCompletion 179]could not release a cache lock

org.hibernate.cache.CacheException: java.lang.IllegalStateException: The org.hibernate.cache.UpdateTimestampsCache Cache is not alive.

at org.hibernate.cache.EhCache.put(EhCache.java:125)

at org.hibernate.cache.UpdateTimestampsCache.invalidate(UpdateTimestampsCache.java:69)

at org.hibernate.engine.ActionQueue.afterTransactionCompletion(ActionQueue.java:174)

at org.hibernate.impl.SessionImpl.afterTransactionCompletion(SessionImpl.java:424)

at org.hibernate.jdbc.JDBCContext.afterTransactionCompletion(JDBCContext.java:225)

at org.hibernate.transaction.JDBCTransaction.rollback(JDBCTransaction.java:174)

at org.springframework.orm.hibernate3.HibernateTransactionManager.doRollback(HibernateTransactionManager.java:577)

at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:631)

at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:608)

at org.springframework.transaction.interceptor.TransactionAspectSupport.completeTransactionAfterThrowing(TransactionAspectSupport.java:328)

at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:111)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)

at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:652)

at com.sinosoft.sepmis.inspection.service.InspectionDataServiceImpl$$EnhancerByCGLIB$$d9f54f39.saveInspectionData()

at com.sinosoft.sepmis.util.ConnectionTelnet.execute(ConnectionTelnet.java:319)

at com.sinosoft.sepmis.util.InspectionUtil.inspectExecute(InspectionUtil.java:331)

at com.sinosoft.sepmis.util.InspectionUtil.partOfManual(InspectionUtil.java:259)

at com.sinosoft.sepmis.util.ThreadManageUtil.startInspect(ThreadManageUtil.java:45)

at com.sinosoft.sepmis.util.ThreadManageUtil.run(ThreadManageUtil.java:31)

at java.lang.Thread.run(Thread.java:735)

Caused by:

java.lang.IllegalStateException: The org.hibernate.cache.UpdateTimestampsCache Cache is not alive.

at net.sf.ehcache.Cache.checkStatus(Cache.java:1204)

at net.sf.ehcache.Cache.put(Cache.java:549)

at net.sf.ehcache.Cache.put(Cache.java:522)

at org.hibernate.cache.EhCache.put(EhCache.java:119)

... 19 more

原因分析:

由于程序后台一直在运行定时程序,而且定时程序的运行为7*24小时。在这期间程序会出现八小时闲置的情况,即程序和数据库之间没有任何交换操作。这样Mysql数据库端会主动动断开连接。这样如果定时启动后,要想获取到Mysql的连接,自然就会报出异常。

方法一,Mysql数据库延长wait_timeout参数时间(不推荐):

通过修改my.ini(Linux系统为my.cnf)文件中wait_timeout=xxx,即便是这样系统在闲着超过此参数设置时间后依然会出现异常。(注意:此参数单位为秒)

也可以通过mysql命令设置。

Mysql > set global wait_timeout=xxx;

设置后重启mysql服务,命令如下:

service mysql restart

登录mysql查看是否生效:

Mysql > show global variables like 'wait_timeout';

14b671846ec03313063f48059e8add84.png

方法二,修改hibernate 中配置属性(不推荐):

代码如下

true property>

true property >

true property>

个人通过试验发现,这种方法并没有起到效果。不知道网上的写文章的人是怎么解决的。

方法三,使用第三方数据库连接池(推荐):

现在第三方数据库连接池使用较多的为c3p0,proxool等,在性能上c3p0稍好一些,原因c3p0数据库连接池,底层有一个定时查看数据库连接是否有效的参数。而且Hibernate的api中也推荐使用第三方数据库连接池,因为Hibernate本身的数据库连接池过于简单、本身存在bug。c3p0参数配置如下:

查看mysql数据库连接池情况,命令如下:

Mysql> show processlist;

c8957c064b954d7c5be775fcecf7188d.png

ps:最近在在停起程序的时候我发现了一个问题,就算是我停止了服务,但是程序和mysql数据库之间的连接数依然没有断开,后来经查资料和同事请教,我发现在上边的c3p0配置存在一个小bug。因为我将c3p0交给Spring进行管理,但是在上边注入的bean中没有加上destroy-method="close"这个属性。 也就是说Spring是不能正常销毁连接的,由此出现了我说的问题。

写在这里以供大家警示,真是马虎啊,竟然忘记了销毁,实在不应该。

... ...

参考文章:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值