c3p0连接池不关闭连接

问题描述:

我有一个使用c3p0 0.9.1.2,hibernate 3.2.1.ga和spring 2.5.5。问题是数据库连接没有关闭。下面是日志:c3p0连接池不关闭连接

[火星22 2012 12:29:56091] DEBUG com.mchange.v2.resourcepool.BasicResourcePool [ “HTTP-APR-8080” -exec-4]测试获取 - 池是已经超过了。 [托管:20;最大:20] [22 mars 2012 12:29:56,091] DEBUG com.mchange.v2.resourcepool.BasicResourcePool [“http-apr-8080”-exec-4] awaitAvailable():com.mchange.v2.c3p0。 [email protected] [22 mars 2012 12:29:56,091] DEBUG com.mchange.v2.resourcepool.BasicResourcePool [“http-apr-8080”-exec-4] trace com.mchange.v2.resourcepool.BasicResourcePool @ 6b0524 [管理:20,未使用的:0,排除:0](例如[email protected]

这里的数据源配置:

<!-- Local DataSource that works in any environment --> 
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> 
    <property name="driverClass" value="${database.driver}"/> 
    <property name="jdbcUrl" value="${database.url}"/> 
    <property name="user" value="${database.user}"/> 
    <property name="password" value="${database.password}"/> 
    <!--<property name="connectionCustomizerClassName" value="org.xxx.webapp.common.persistence.WatchConnectionCustomizer"/>--> 
    <property name="maxStatements" value="500"/> 
    <property name="maxIdleTime" value="1800"/> 
    <property name="maxPoolSize" value="100"/> 
    <property name="minPoolSize" value="2"/> 
    <property name="initialPoolSize" value="2"/> 
    <property name="acquireIncrement" value="3"/> 
    <property name="idleConnectionTestPeriod" value="3000"/> 
</bean> 



<bean id="sessionFactory" 
    class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" > 
    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">${hibernate.dialect}</prop> 
      <prop key="hibernate.show_sql">false</prop> 
      <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop> 
      <prop key="hibernate.connection.autocommit">${hibernate.connection.autocommit}</prop> 
      <prop key="hibernate.transaction.auto_close_session">${hibernate.transaction.auto_close_session}</prop> 
      <prop key="hibernate.connection.release_mode">${hibernate.connection.release_mode}</prop> 
      <prop key="hibernate.bytecode.use_reflection_optimizer">${hibernate.bytecode.use_reflection_optimizer}</prop> 
      <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop> 
      <prop key="hibernate.cache.use_query_cache">true</prop> 
      <prop key="hibernate.cache.use_second_level_cache">true</prop> 
      <prop key="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.EhCacheRegionFactory</prop> 
     </props> 
    </property> 

<property name="annotatedClasses"> 
    <list> 
     ... 
    </list> 
    </property> 

    <property name="dataSource"> 
    <ref bean="dataSource" /> 
    </property> 


</bean> 

<bean id="transactionManager" 
    class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
    <property name="sessionFactory"> 
     <ref bean="sessionFactory" /> 
    </property> 
</bean> 

这是我们通用的DAO提前

public class GenericDAO<T, PK extends Serializable> extends HibernateDaoSupport 
    implements IGenericDAO<T, PK> { 

private Class<T> clazz; 
private Logger logger = Logger.getLogger(GenericDAO.class); 
private static Session session; 

public GenericDAO(Class<T> clazz) { 
    this.clazz = clazz; 
} 

public void refresh(T instanceToRefresh) throws DataAccessException { 
    getHibernateTemplate().refresh(instanceToRefresh); 
    //getCurrentSession().refresh(instanceToRefresh); 
} 

public void saveOrUpdate(T instanceToSaveOrUpdate) 
     throws DataAccessException { 
    //getCurrentSession().saveOrUpdate(instanceToSaveOrUpdate); 
    getHibernateTemplate().saveOrUpdate(instanceToSaveOrUpdate); 
} 

public void persist(T instanceToPersist) throws DataAccessException { 
    getHibernateTemplate().persist(instanceToPersist); 
    //getCurrentSession().persist(instanceToPersist); 
} 

@SuppressWarnings("unchecked") 
public T merge(T instanceToMerge) throws DataAccessException { 
    T instanceMerged = (T) getHibernateTemplate().merge(instanceToMerge); 
    //T instanceMerged = (T) getCurrentSession().merge(instanceToMerge); 
    return instanceMerged; 
} 

@SuppressWarnings("unchecked") 
public PK save(T newInstance) throws DataAccessException { 
    return (PK) getHibernateTemplate().save(newInstance); 
    //return (PK) getCurrentSession().save(newInstance); 
} 

public void delete(T persistentObject) throws DataAccessException { 
    getHibernateTemplate().delete(persistentObject); 
    //getCurrentSession().delete(persistentObject); 
} 

@SuppressWarnings("unchecked") 
public T load(PK id) { 
    return (T) getHibernateTemplate().get(clazz, id); 
    //return (T) getCurrentSession().get(clazz, id); 
} 

public void update(T transientObject) throws DataAccessException { 
    //getCurrentSession().update(transientObject); 
    getHibernateTemplate().update(transientObject); 
} 

@SuppressWarnings("unchecked") 
public List<T> loadAll() throws DataAccessException { 
    //Session session = this.getCurrentSession(); 
    //return session.createQuery("from " + clazz.getName()).list(); 
    return getHibernateTemplate().loadAll(clazz); 
} 
} 

感谢。

+1

向我们展示了DAO在appication上下文和java代码中的声明。 – ManuPK 2012-03-22 15:15:17

+0

我已添加了我们的通用DAO – Oualid 2012-03-22 15:39:16

通常,连接通过休眠自动关闭。然而,要注意以下几点:

  • 长期运行的事务可能会占用连接
  • 不当会话管理可能意味着你不关闭会话,这反过来又意味着连接仍然在使​​用

使用弹簧时的典型设置是用@Transactional注释您的服务方法。这样春天会管理你的交易和会话。

+2

非常感谢,您的回答确实对我有帮助,我将@Transactional添加到所有服务方法中,问题解决了。 – Oualid 2012-03-22 18:31:11

+0

@Bozho:你指的是'不正确的会话管理'。你能举一个在Spring/Hibernate环境中正确的会话管理的例子吗? – spier 2012-06-03 12:53:53

+0

每个请求(或每个对话)打开和关闭一个会话,而不是忘记关闭它 – Bozho 2012-06-03 15:37:07

我们在dispatcher-servlet.xml文件中使用了以下行,并且数据库物理连接现在正在关闭。

<tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager"/>