Spring 配置C3p0连接池的导致的问题

项目遇到了一个瓶胫,当用户访问并发数不大的情况下,系统运行正常,但是当并发数达到一定量的时候,就会出现“无法获取连接,网络适配器断开”

 

首先确定网络是否连接正常。WEB服务器是不是开了防火Q,是否中了ARP之类的病毒。发现都是正常的。

网络和服务器没有问题后,就检查ORACLE数据库,发并连接正常,但是用户会话会有些异常,系统启动时会话量增大,运行中居然变小。

那确定应该是程序的问题。首先将问题锁定在数据库连接管理上。

 

项目中采用的是C3P0连接池来管理数据库连接,系统架构是采用Hibernate+Spring+Strtus实现,由Spring整合C3P0连接池来管理连接。下面是配置文件:

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-lazy-init="true">
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location">
            <value>classpath:/database.properties</value>
        </property>
    </bean> 
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName">
            <value>${jdbc.driverClassName}</value>
        </property>
        <property name="url">
            <value>${jdbc.url}</value>
        </property>
        <property name="username">
            <value>${jdbc.username}</value>
        </property>
        <property name="password">
            <value>${jdbc.password}</value>
        </property>
    </bean>
	<!-- Hibernate SessionFactory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource">
            <ref local="dataSource" />
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect"> ${hibernate.dialect} </prop>
                <prop key="hibernate.show_sql"> ${hibernate.show_sql} </prop>
                <prop key="hibernate.c3p0.minPoolSize"> ${hibernate.c3p0.minPoolSize}</prop>
                <prop key="hibernate.c3p0.maxPoolSize"> ${hibernate.c3p0.maxPoolSize} </prop>
                <prop key="hibernate.c3p0.timeout"> ${hibernate.c3p0.timeout} </prop>
                <prop key="hibernate.c3p0.max_statement"> ${hibernate.c3p0.max_statement} </prop>
                <prop key="hibernate.cache.provider_class">cn.com.jody.common.framework.hibernate.MemcachedCacheProvider</prop>
                <prop key="memcached.servers">192.168.1.0:8888</prop>
                <prop key="memcached.server.weights">1</prop>
                <prop key="memcached.failover">true</prop>
                <prop key="memcached.initConn">10</prop>
                <prop key="memcached.minConn">10</prop>
                <prop key="memcached.maxConn">50</prop>
                <prop key="memcached.maintSleep">30</prop>
                <prop key="memcached.nagle">false</prop>
                <prop key="memcached.socketTO">3000</prop>
                <prop key="memcached.aliveCheck">true</prop>
                <prop key="memcached.*">20m</prop>
                <prop key="hibernate.cache.use_query_cache">false</prop>
                <prop key="hibernate.cache.use_second_level_cache">true</prop>
                <prop key="hibernate.jdbc.batch_size">100</prop>
                <prop key="hibernate.jdbc.fetch_size">50</prop>
                <prop key="hibernate.default_batch_fetch_size">50</prop>
                <prop key="hibernate.cache.use_minimal_puts">true</prop>
                <prop key="hibernate.connection.release_mode">after_transaction</prop>
            </props>
        </property>
        <property name="mappingDirectoryLocations">
            <list>
                <value>classpath:/ormappings</value>
            </list>
        </property>
    </bean>

	<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory">
            <ref local="sessionFactory" />
        </property>
    </bean>
</beans>

 

 细细检查发现,原来是上面的配置存在问题。

 

数据源(dataSource)是通过Spring的“org.springframework.jdbc.datasource.DriverManagerDataSource”类通过连接JDBC驱动获取的数据库源。

 

Hibernate的(sessionFactory)是通过Spring的“org.springframework.orm.hibernate3.LocalSessionFactoryBean”来管理的。这个配置中虽然配置了C3P0连接池:

<prop key="hibernate.c3p0.minPoolSize"> ${hibernate.c3p0.minPoolSize}</prop>
                <prop key="hibernate.c3p0.maxPoolSize"> ${hibernate.c3p0.maxPoolSize} </prop>
                <prop key="hibernate.c3p0.timeout"> ${hibernate.c3p0.timeout} </prop>
                <prop key="hibernate.c3p0.max_statement"> ${hibernate.c3p0.max_statement} </prop>

 

但是却没有作用,对Spring 管理的数据源(dataSource)没有改变。当Hibernate中调用一个sessionFactory时,得到的数据源(dataSource)只是在Spring中通过JDBC驱动获取和数据源。没有通过数据库连接池来管理数据库连接。所以当数据库连接达到一定的数量时,就出现无法获取数据库连接的现像。

 

修改Application.xml配置文件:

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-lazy-init="true">
	<!-- ========================= RESOURCE DEFINITIONS ========================= -->
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:/database.properties"/>


    </bean> 
	<!-- Local DataSource that works in any environment -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClassName}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="maxPoolSize" value="${hibernate.c3p0.maxPoolSize}"/>
        <property name="minPoolSize" value="${hibernate.c3p0.minPoolSize}"/>
        <property name="idleConnectionTestPeriod" value="30"/>
        <property name="acquireIncrement" value="5"/>
        <property name="properties">
            <props>
                <prop key="user">${jdbc.username}</prop>
                <prop key="password">${jdbc.password}</prop>
            </props>
        </property>
    </bean>
	<!-- Hibernate SessionFactory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource">
            <ref local="dataSource" />
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect"> ${hibernate.dialect} </prop>
                <prop key="hibernate.show_sql"> ${hibernate.show_sql} </prop>




                <prop key="hibernate.cache.provider_class">cn.com.jody.common.framework.hibernate.MemcachedCacheProvider</prop>
                <prop key="memcached.servers">192.168.1.0:8888</prop>
                <prop key="memcached.server.weights">1</prop>
                <prop key="memcached.failover">true</prop>
                <prop key="memcached.initConn">10</prop>
                <prop key="memcached.minConn">10</prop>
                <prop key="memcached.maxConn">50</prop>
                <prop key="memcached.maintSleep">30</prop>
                <prop key="memcached.nagle">false</prop>
                <prop key="memcached.socketTO">3000</prop>
                <prop key="memcached.aliveCheck">true</prop>
                <prop key="memcached.*">20m</prop>
                <prop key="hibernate.cache.use_query_cache">false</prop>
                <prop key="hibernate.cache.use_second_level_cache">true</prop>
                <prop key="hibernate.jdbc.batch_size">100</prop>
                <prop key="hibernate.jdbc.fetch_size">50</prop>
                <prop key="hibernate.default_batch_fetch_size">50</prop>
                <prop key="hibernate.cache.use_minimal_puts">true</prop>
                <prop key="hibernate.connection.release_mode">after_transaction</prop>
            </props>
        </property>
		        <property name="mappingDirectoryLocations">
            <list>
                <value>classpath:/orm</value>
            </list>
        </property>
    </bean>

	<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory">
            <ref local="sessionFactory" />
        </property>
    </bean>
</beans>

 这个配置中,

数据源(dataSource)是通过C3P0的“com.mchange.v2.c3p0.ComboPooledDataSource”类通过连接JDBC驱动获取的数据库源,并且有连接池的管理。

然后,

Hibernate的(sessionFactory)是通过Spring的“org.springframework.orm.hibernate3.LocalSessionFactoryBean”来管理的。这个配置中虽然配置了C3P0连接池:

这样,Spring管理的是C3P0连接池中的连接事务,Hibernate调用的是C3P0连接池中的连接,因为有了连接池的管理,所以当用户并发量大时,在处理上也可以胜任。当然,C3P0也是有一个并发量限制,单机处理并发量问题,还是不现实,集群才是最好的办法。

 

以上是总结项目中的问题。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值