天天看點

spring+hibernate+c3p0整合連結池配置-連接配接無法釋放問題(已經解決)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
 xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="
 http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context-3.2.xsd
 http://www.springframework.org/schema/tx
 http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop-3.2.xsd"
 default-autowire="byName">
 <context:property-placeholder location="classpath:jdbcConfig.properties" />
 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
  destroy-method="close">
  <property name="driverClass" value="${jdbc.driverClassName}" />
  <property name="jdbcUrl" value="${jdbc.url}" />
  <property name="user" value="${jdbc.username}" />
  <property name="password" value="${jdbc.password}" />
  <property name="minPoolSize" value="5" />
  <property name="maxPoolSize" value="20" />
  <property name="maxStatements" value="10" />
  <property name="idleConnectionTestPeriod" value="3000" />
  <property name="loginTimeout" value="300" />
 </bean>
 <bean id="sessionFactory"
  class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
  <property name="dataSource">
   <ref local="dataSource" />
  </property>
  <property name="hibernateProperties">
   <props>
    <prop key="hibernate.show_sql">true</prop>
    <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
    <prop key="hibernate.format_sql">true</prop>
    <prop key="hibernate.use_sql_comments">true</prop>
   </props>
  </property>
  <property name="packagesToScan" value="com" />
 </bean>
 <context:component-scan base-package="com" />
 <!-- 事務管理器 -->
 <bean id="transactionManager"
  class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory" />
  <property name="dataSource">
   <ref local="dataSource" />
  </property>
 </bean>
 <!-- 支援事務 @Transactional 标記 -->
 <tx:annotation-driven transaction-manager="transactionManager" />
</beans>
           

以上配置是spring+hibernate+c3p0整合連結池配置,通過代碼全注解的方式增加事物管理,連接配接池等

前不久一直被一個問題困擾着, getHibernateTemplate().getSessionFactory().openSession(); 通過這種方式打開的session不會自動關閉,現象時查詢多次之後連接配接池滿了,不會再繼續查詢了

日志資訊如下

2014-06-06 15:16:50,654 [btpool0-4] DEBUG AbstractBeanFactory : Returning cached instance of singleton bean 'transactionManager'
2014-06-06 15:16:50,655 [btpool0-4] DEBUG AbstractPlatformTransactionManager : Creating new transaction with name [com.*.*.service.ActivityService.findAllByPage]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
2014-06-06 15:16:50,655 [btpool0-4] DEBUG HibernateTransactionManager : Opened new Session [[email protected]] for Hibernate transaction
2014-06-06 15:16:50,655 [btpool0-4] DEBUG HibernateTransactionManager : Preparing JDBC Connection of Hibernate Session [[email protected]]
2014-06-06 15:16:50,655 [btpool0-4] DEBUG BasicResourcePool : trace [email protected] [managed: 20, unused: 0, excluded: 0] (e.g. [email protected])
2014-06-06 15:16:50,656 [btpool0-4] DEBUG HibernateTransactionManager : Exposing Hibernate transaction as JDBC transaction [[email protected]]
2014-06-06 15:16:50,657 [btpool0-4] DEBUG BasicResourcePool : acquire test -- pool is already maxed out. [managed: 20; max: 20]
2014-06-06 15:16:50,657 [btpool0-4] DEBUG BasicResourcePool : awaitAvailable(): [email protected]
2014-06-06 15:16:50,658 [btpool0-4] DEBUG BasicResourcePool : trace [email protected] [managed: 20, unused: 0, excluded: 0] (e.g. [email protected])
           

後來通過網上查找資料看到這麼一篇内容 http://blog.csdn.net/a549324766/article/details/7332818

這個是hibernate與spring整合開發,讓DAO繼承了spring的HibernateDaoSupport,這樣的确能夠提高開發效率 ,但是不夠靈活,而且使DAO層依賴于spring的api,增加了耦合。但是不考慮複用的話還可以。

    下面一個一個的分析: this.getsession實際上是調用了父類中的方法獲得session。使用spring管理hibernate的SessionFactory的時候,這個方法會從session池中拿出一session.這樣做有可能有問題,就是超session池連接配接數的時候,spring無法自動的關閉session。 不推薦使用

     this.getHibernateTemplate().getSessionFactory().getCurrentSession()從spring管理的sessionFactory中建立一個綁定線程的session.spring會根據該線程的執行情況來自動判斷是關閉session還是延遲關閉。這樣做可以避免手動的管理實務,同時一個線程最多開啟和關閉一次session又可以提高程式的性能。 極力推薦使用這種方法 

     this.getHibernateTemplate().getSessionFactory().OpenSession。這種方法從spring管理的sessionFactory中建立一個session,此session不是線程綁定的。當執行完一個實務的時候自動關閉session.這種方法不用手動管理實務,但是同一個線程多次的開啟和關閉session,浪費系統資源和影響執行效率,正常情況下還是不要用了。

其中this.getSession這個方法我也用過,這個确實也會将連接配接關閉,當時對于樓主提到的問題不知道怎麼測試,

第二個問題完美的解決了,我遇到的連接配接池無法關閉的問題而且樓主也推薦使用,應該找到最終的解決辦法了

第三個,就是我前面一直用的,需要手動關閉連接配接

對于網上還有一種說法,

http://bbs.csdn.net/topics/340092096

問題已經解決,原來在配置hibernater時少配了一個屬性:

<prop key="hibernate.connection.release_mode">after_statement</prop>

唉!不懂是此屬性值預設是on_close,就是session.close();時關閉連接配接,但我在調用這查詢時,使用手動session.close();還是一樣的結果。。。。

該配置對于我來說一點用都沒有,不知道是什麼場景下使用

不過總算搞定連接配接池問題了,已經工作的時候,也經常聽别人說你們要用getCurrentSession,而不要新開連接配接,新開的需要自己手動關閉,大概道理就是這個了

繼續閱讀