message from server: "Too many connections"

跑项目时,发现log日志报如下异常:


com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections"数据库连接不够用。


我用的是SSH框架下的hibernateTemplate来操作数据库的,数据库连接池用的是c3p0(默认的最大连接数是100),mysql数据库提供的最大连接数是150:可以通过  show variables like '%max_connections%';查看数据库可提供的最大连接数,而show status like 'Threads%'可以通过Threads_connections监控当前数据库打开的连接数.


当时分析后,认为有2中可能的原因:

(1)hibernateTemple没有及时释放数据库连接。

(2)数据库的连接数确实不够用。


对于原因(1):

后来查了下 hibernate 的数据库连接释放策略,有如下4中策略:

default  :默认方式,在spring中配置事务管理,由于事务颗粒度比较小,事务执行结束,也不会触发释放的操作,直至达到连接设置回收的最大超时时间才能回收连接,连接

                  会迟迟不释放,导致连接池被占满。

on_close  :session关闭时,连接释放。

after_transaction  :事务提交后,连接释放。

after_statement  :每次执行statement 后就释放当前连接。

解决方案:由于hibernateTemplate每次执行完之后会自动关闭session,看如下源码:

protected Object doExecute(HibernateCallback action, boolean enforceNewSession, boolean enforceNativeSession)
throws DataAccessException { ......
finally {
if (existingTransaction) {
logger.debug("Not closing pre-bound Hibernate Session after HibernateTemplate");
disableFilters(session);
if (previousFlushMode != null) {
session.setFlushMode(previousFlushMode);
}
}
else {
// Never use deferred close for an explicitly new Session.
if (isAlwaysUseNewSession()) {
SessionFactoryUtils.closeSession(session);
}
else {
SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, getSessionFactory());
}
}
}
}
SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, getSessionFactory());

就是这段代码会自动关闭sessin。

所以我是用了on_close的策略去释放数据库连接,具体配置如下:(ps:如果你已经把transaction注入了dao包,采用after_transaction策略更好)

 <prop key="hibernate.connection.release_mode">on_close</prop>

一般问题到此就会完美解决,但是楼主我比较悲催。


配完上面的策略后,楼主我的项目确实成功跑起来了。但是,跑了一会后又发现:

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections"

。。。。。。

当时心中一万只什么的路过。难道是原因(2)? 我又对数据库 set global max_connections = 10000; (这条语句可以扩大数据库提供的连接数)并把连接池的最大连接数也设置到10000。项目再跑,发现上面的异常确实没了,但我的eclipse卡死了。。。又通过show status like 'Threads%'发现打开了1000多个连接。。。

这不应该啊,我只是同时并发了20条请求而已,算满也只需要60个连接啊。

后来,我只能认定c3p0数据库连接池的问题了。机缘巧合之下我发现了这个超高性能的数据库连接池:boneCP!    我的配置如下:


用了bongcp后,终于完美解决了com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections"的问题。<prop key="hibernate.connection.release_mode">on_close</prop>这个配置也起作用了!最重要的是bonecp的这条配置

<property name="releaseHelperThreads" value="3" />它自带连接释放机制。相当于多加了一条释放连接的保险!

最终要的是bonecp的性能比c3p0高了一倍左右(我项目的实测)。到此楼主的问题完美解决。

bonecp的详细介绍请参考:

http://zhoufoxcn.blog.51cto.com/792419/438277/


如果还不行的话,请参考我的

SSH下的Spring配置文件 这篇博客配置你的sping文件














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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值