数据库连接池,hibernate连接池(解决mysql 8小时)

不久前做了一个小程序,在本地正常运行后,放到服务器上,配置完后也是正常运行的。过了一段时间登录服务器,发现出现了:
org.hibernate.exception.JDBCConnectionException: could not execute query
这个Exception,这个异常说的是java数据库连接出现了异常,怎么会出现这种异常的呢,开发时没有的啊。
其实这是由于Hibernate内建连接池(connection pool)的原因,平时我们使用hibernate时,配置hibernate.cfg.xml属性时,默认是不指明使用使用哪种连接池的,那么hibernate就使用了内建的连接池,这个连接池不是很智能,他不会检查池内的连接是否有效,当用户需要查询数据库时,直接使用池内的connection还是查询,可是一旦池内的连接是无效的话,就会出现上面说的Exception。至于connection无效的原因,那是因为mysql默认了一个连接在8小时内没有操作就自动断开(这就是传说中的8小时)。
那么我遇到的问题就很清晰了,刚刚将程序配置上服务器上时,hibernate内建连接池从数据库中获得了connection,这些connection都是新鲜火辣的,自然可以正常工作,可是当放置程序一段时间后,mysql断开了没有使用的connection,我们再次尝试去访问页面,这时连接池中的connection是无效的了,那么我们的访问只能是以失败告终。
那么怎么解决问题呢。既然hibernate内建的连接池没有那么理想,就换一个嘛,这跟谈对象是一样的道理,不适合你的为什么要死死不放开呢?hibernate官方的文档也说了,他们的连接池推荐是在开发的时候使用=.=.
这里我选用的连接池是 C3P0。
其实这个问题也是最近才发现,这次项目没有使用spring进行管理,也就暴露出来了。
不扯远,说下怎么配置C3P0.
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.timeout">300</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
上面是一个国外网站介绍hibernate配置C3P0的文章:
http://www.mkyong.com/hibernate/how-to-configure-the-c3p0-connection-pool-in-hibernate/
我测试了下,不行,这样的话其实没有启动C3P0的连接池。应该这样写:
<!-- C3P0连接池设定-->
<property name=">org.hibernate.connection.C3P0ConnectionProvider</property>
<!-- 最大连接数 -->
<property name=">20</property>
<!-- 最小连接数 -->
<property name=">2</property>
<!-- 获得连接的超时时间,如果超过这个时间,会抛出异常,单位毫秒 -->
<property name=">120</property>
<!-- 最大的PreparedStatement的数量 -->
<property name=">30</property>
<!-- 每隔120秒检查连接池里的空闲连接 ,单位是秒-->
<property name=">240</property>
<!-- 当连接池里面的连接用完的时候,C3P0一下获取的新的连接数 -->
<property name=">2</property>
<!-- 每次都验证连接是否可用 -->
<property name=">true</property>
<property name=">true</property>
上面的语句指定了使用C3P0.
启动一下项目,却出现了一个问题:
java.lang.ClassNotFoundException: com.mchange.v2.c3p0.DataSources
很明显是缺包了。
导入对应的包,我这里使用的是 c3p0-0.8.5.2.jar ,可以去网上找到。
再次启动项目,当第一次访问数据库时,看到了这一句:
Initializing c3p0 pool... com.mchange.v2.c3p0.PoolBackedDataSource@16856e3 [ connectionPoolDataSource -> com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@1336dc2 [ acquireIncrement -> 2, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, idleConnectionTestPeriod -> 240, initialPoolSize -> 2, maxIdleTime -> 120, maxPoolSize -> 20, maxStatements -> 30, maxStatementsPerConnection -> 0, minPoolSize -> 2, nestedDataSource -> com.mchange.v2.c3p0.DriverManagerDataSource@fda6e5 [ description -> null, driverClass -> null, factoryClassLocation -> null, jdbcUrl -> jdbc:mysql://localhost:3306/article2011?useUnicode=true&characterEncoding=GBK, properties -> {user=******, password=******} ] , preferredTestQuery -> null, propertyCycle -> 300, testConnectionOnCheckin -> false, testConnectionOnCheckout -> true, usesTraditionalReflectiveProxies -> false ] , factoryClassLocation -> null, numHelperThreads -> 3, poolOwnerIdentityToken -> 16856e3 ]
就是说C3P0已经正常启动了,从语句中可以看到连接池的一些参数,可以根据需要进行修改,也就是在配置文件里设置一下就好了。
Tags:  java连接池 连接池 数据库连接池

延伸阅读

最新评论

发表评论