随笔-193  评论-90  文章-8  trackbacks-0
摘自springside论坛

一、
经过N多试验,终于自己把这个问题搞定了。

网上关于C3P0在spring中的配置,几乎没有完全正确的(至少我还没发现)。查了c3p0的文档,又试验过N次。得出如下配置是正确的:


<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"   destroy-method="close">
         <property name="driverClass"><value>${jdbc.driverClassName}</value></property>
         <property name="jdbcUrl"><value>${jdbc.url}</value></property>               
         <property name="user"><value>${jdbc.username}</value></property>
         <property name="password"><value>${jdbc.password}</value></property>
         
         <property name="minPoolSize"><value>1</value></property>
         <property name="maxPoolSize"><value>20</value></property>
         <property name="maxIdleTime"><value>1800</value></property>
         <property name="acquireIncrement"><value>2</value></property>
         <property name="maxStatements"><value>0</value></property>
         <property name="initialPoolSize"><value>2</value></property>
         <property name="idleConnectionTestPeriod"><value>1800</value></property>
         <property name="acquireRetryAttempts"><value>30</value></property>
         <property name="breakAfterAcquireFailure"><value>true</value></property>
         <property name="testConnectionOnCheckout"><value>false</value></property>
         
         <!--
            <property name="properties">
          <props>              
              <prop key="c3p0.minPoolSize">1</prop>
              <prop key="c3p0.maxPoolSize">10</prop>
              <prop key="c3p0.maxIdleTime">1800</prop>              
              <prop key="c3p0.acquireIncrement">2</prop>
              <prop key="c3p0.maxStatements">0</prop>
                    <prop key="c3p0.initialPoolSize">2</prop>
              <prop key="c3p0.idleConnectionTestPeriod">1800</prop>
              <prop key="c3p0.acquireRetryAttempts">30</prop>
              <prop key="c3p0.breakAfterAcquireFailure">true</prop>
              <prop key="c3p0.testConnectionOnCheckout">true</prop>
              <prop key="user">root</prop>
              <prop key="password">999999</prop>
              
          </props>
         </property>
        -->      
</bean>

<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  <property name="dataSource" ref="dataSource"/>
  <property name="mappingDirectoryLocations">
      <list>
   <value>classpath:/com/licaionline/domain/</value>
      </list>
  </property>
  <property name="hibernateProperties">
   <props>
    <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
     <prop key="hibernate.show_sql">true</prop>
    <prop key="hibernate.generate_statistics">true</prop>
                <prop key="hibernate.connection.release_mode">auto</prop>                     
                <prop key="hibernate.autoReconnect">true</prop>
                <prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
                <!--
    <prop key="hibernate.useUnicode"></prop>
    <prop key="hibernate.characterEncoding"></prop>
    <prop key="hibernate.default-lazy-init"></prop>
                <prop key="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</prop>     
    -->
                                
                <!--
                <prop key="hibernate.c3p0.acquire_increment">2</prop>
                <prop key="hibernate.c3p0.idle_test_period">1800</prop>
                <prop key="hibernate.c3p0.timeout">1800</prop>
                <prop key="hibernate.c3p0.max_size">30</prop>
                <prop key="hibernate.c3p0.min_size">2</prop>
                <prop key="hibernate.c3p0.max_statements">50</prop>
    -->         
   </props>
  </property>




注意:注释掉的那些,都是错误的。网上流行的,基本上跟注释掉的那些差不多。配错了,并无异常,还是能正常使用。但是所作的配置不起作用。


二、
起作用的,是datasource里面的这一句:
<property name="maxIdleTime"><value>1800</value></property>

这儿设置成每隔1800秒就扫描一次,检查一下空闲的链接。所以,用户基本上不会得到空闲的链接了。

如果再不放心,
<property name="testConnectionOnCheckout"><value>false</value></property>
这儿设置成true。每次连接之前,都要测一下。但是这样会影响效率。


三、

解决的方法有3种:

增加wait_timeout的时间。
减少Connection pools中connection的lifetime。
测试Connection pools中connection的有效性。
当然最好的办法是同时综合使用上述3种方法,下面就DBCP和C3P0分别做一说明,假设wait_timeout为默认的8小时

DBCP增加以下配置信息:

//set to 'SELECT 1'   
validati   
//set to 'true'   
testWhileIdle = "true"     
//some positive integer   
timeBetweenEvictionRunsMillis = 3600000   
//set to something smaller than 'wait_timeout'   
minEvictableIdleTimeMillis = 18000000   
//if you don't mind a hit for every getConnection(), set to "true"   
test   

C3P0增加以下配置信息:

//set to 'SELECT 1'      
preferredTestQuery = 'SELECT 1'     
//set to something much less than wait_timeout, prevents connections from going stale   
idleConnectionTestPeriod = 18000      
//set to something slightly less than wait_timeout, preventing 'stale' connections from being handed out   
maxIdleTime = 25000     
//if you can take the performance 'hit', set to "true"   
testConnectionOnCheckout = true     

更多的配置信息大家可以查看C3P0文档,Connector/J文档,以及DBCP的文档。

posted on 2007-01-10 15:33 一凡 阅读(3868) 评论(10)  编辑  收藏 所属分类: JAVA FRAMEWORK

评论:
# re: 每日访问数据库失败问题 2007-03-18 15:18 | 流浪汗
我这个问题

同感,当去掉<property name="properties">
时正确

否则第一次连接时出错

org.hibernate.exception.JDBCConnectionException: could not execute query

然后找到你的文章,收藏了.

你总结的很好

我的环境是
spring 2.0
hibernate 3.1.2
c3p0-0.9.0.4  回复  更多评论
  
# re: 每日访问数据库失败问题 2007-10-19 10:42 | mashiguang
c3p0的最大空闲时间为什么不起作用呢.

有时间的话帮我看一下这个贴子,http://www.javaeye.com/topic/133254
谢谢.  回复  更多评论
  
# re: 每日访问数据库失败问题 2007-10-19 10:50 | 一凡
配置文件里加上这句
<property name="maxIdleTime"><value>1800</value></property>  回复  更多评论
  
# re: 每日访问数据库失败问题 2007-10-19 10:51 | 一凡
不要在程序里设置,让它自己初始化就好  回复  更多评论
  
# re: 每日访问数据库失败问题 2007-10-19 10:54 | mashiguang
我没有用spring,
ComboPooledDataSource dataSource=new ComboPooledDataSource();
dataSource.setMaxIdleTime(9);
这样设置不是一样的吗??  回复  更多评论
  
# re: 每日访问数据库失败问题 2007-10-19 11:06 | 一凡
按理说应该没问题,连接池这东西说不好,我遇到过程序写不行,在配制文件里就没问题  回复  更多评论
  
# re: 每日访问数据库失败问题 2007-10-19 11:11 | mashiguang
好的,我试一下,谢谢你.  回复  更多评论
  
# re: 每日访问数据库失败问题[未登录] 2008-05-19 14:02 | alfred
<prop key="c3p0.idleConnectionTestPeriod">1800</prop>
<prop key="c3p0.maxIdleTime">1800</prop>
这两都都是检查空闲的,maxidelteime检查到空闲会丢掉。
idleConnectionTestPeriod 有什么作用呢?  回复  更多评论
  
# re: 每日访问数据库失败问题 2010-06-05 21:03 | moka
<!--每30秒检查所有连接池中的空闲连接。Default: 0 -->
<property name="idleConnectionTestPeriod">30</property>
指每个连接sleep time只要一到${idleConnectionTestPeriod}秒就将sleep time从头开始计时

<!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime">60</property>
指每个连接sleep time只要一到${maxIdleTime}秒就将该线程杀掉(kill)

只要连接池里的连接一使用,sleep time就会从头开始计时  回复  更多评论
  
# re: 每日访问数据库失败问题 2011-09-30 22:44 | showzh
随便问一句,为什么hibernate.c3p0.timeout没起作用?  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: