2012-03-22 242 views
6

我有一個使用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

回答

11

通常,連接通過休眠自動關閉。然而,要注意以下幾點:

  • 長期運行的事務可能會佔用連接
  • 不當會話管理可能意味着你不關閉會話,這反過來又意味着連接仍然在使​​用

使用彈簧時的典型設置是用@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

0

我們在dispatcher-servlet.xml文件中使用了以下行,並且數據庫物理連接現在正在關閉。

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