sql 連接數不釋放 ,Druid異常:wait millis 40000, active 600, maxActive 600


Hibernate + Spring + Druid 數據庫mysql

由於配置如下

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
		<property name="url" value="${datasource.url}" />
		<property name="username" value="${datasource.username}" />
		<property name="password" value="${datasource.password}" />
 		<!-- 驅動類 -->
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />

		<!-- 默認自動提交狀態。如果不設置,則setAutoCommit 方法將不被調用 -->
		<property name="defaultAutoCommit" value="true" />
		<!-- 屬性類型是字符串,通過別名的方式配置擴展插件,常用的插件有:監控統計用的filter:stat 日志用的filter:log4j 防御sql注入的filter:wall -->
		<!-- <property name="filters" value="stat" /> -->
		<property name="filters" value="config,stat,log4j" />
		<!-- 可以在這個池中同時被分配的有效連接數的最大值 -->
		<property name="maxActive" value="600" />
		<!-- 初始化時建立物理連接的個數。初始化發生在顯示調用init方法,或者第一次getConnection時 -->
		<property name="initialSize" value="2" />
		<!-- 獲取連接時最大等待時間,單位毫秒。配置了maxWait之后,缺省啟用公平鎖,並發效率會有所下降,如果需要可以通過配置useUnfairLock屬性為true使用非公平鎖。-->
		<property name="maxWait" value="40000" />
		<!-- 最小連接池數量 -->
		<property name="minIdle" value="0" />
		<!-- 有兩個含義:1) Destroy線程會檢測連接的間隔時間  2) testWhileIdle的判斷依據,詳細看testWhileIdle屬性的說明 -->
		<property name="timeBetweenEvictionRunsMillis" value="60000" />
		<!-- Destory線程中如果檢測到當前連接的最后活躍時間和當前時間的差值大於 minEvictableIdleTimeMillis,則關閉當前連接 -->
		<property name="minEvictableIdleTimeMillis" value="8000" />
		<!-- 用來檢測連接是否有效的sql,要求是一個查詢語句。如果validationQuery為null,testOnBorrow、testOnReturn、testWhileIdle都不會其作用。
			 在mysql中通常為select 'x',在oracle中通常為select 1 from dual -->
		<property name="validationQuery" value="select 1 from dual" />
		<!-- 建議配置為true,不影響性能,並且保證安全性。申請連接的時候檢測,如果空閑時間大於timeBetweenEvictionRunsMillis,執行validationQuery檢測連接是否有效。 -->
		<property name="testWhileIdle" value="false" />
		<!-- 申請連接時執行validationQuery檢測連接是否有效,做了這個配置會降低性能。-->
		<property name="testOnBorrow" value="false" />
		<!-- 歸還連接時執行validationQuery檢測連接是否有效,做了這個配置會降低性能 -->
		<property name="testOnReturn" value="false" />
		<!-- 要啟用PSCache,必須配置大於0,當大於0時,poolPreparedStatements自動觸發修改為true。在Druid中,不會存在Oracle下PSCache占用內存過多的問題,可以把這個數值配置大一些,比如說100 -->
		<property name="maxOpenPreparedStatements" value="200" />
		<!-- 對於建立時間超過removeAbandonedTimeout的連接強制關閉 -->
		<property name="removeAbandoned" value="true" /> <!-- 打開removeAbandoned功能 -->
		<!-- 180秒,也就是3分鍾 -->
		<property name="removeAbandonedTimeout" value="1800" />
		<!-- 關閉abanded連接時輸出錯誤日志 -->
		<property name="logAbandoned" value="true" />
	</bean>

從配置可以看到,我的連接數max = 600, 但是程序跑到不到一會就報連接數不夠, 獲取不了連接數就一直卡在那里,重啟tomcat服務器,過一會又是這樣

從數據庫  SHOW PROCESSLIST 發現好多連接數在 sleep , sleep 說明連接數沒有被釋放一直在被占用

 

分析思路

1 分析代碼中可能有沒有 未關閉的數據庫連接

2 查看配置文件時候正確

 

代碼中

如果代碼中出現 Session session =  getSession(); 最后最好加上 session.close(); 這樣就手動釋放了這個連接,也可以換一種獲取連接的方式

public class UniversalDao extends HibernateDaoSupport
{
  public void delete(Class clazz, Serializable id)
  {
    getHibernateTemplate().delete(get(clazz, id));
  }

  public List findByCriteria(DetachedCriteria criteria) {
    return getHibernateTemplate().findByCriteria(criteria);
  }
}

這樣 getHibernateTemplate() 獲取數據連接

 

配置文件中

  <!-- 對於建立時間超過removeAbandonedTimeout的連接強制關閉 -->
  <property name="removeAbandoned" value="true" /> <!-- 打開removeAbandoned功能 -->
  <!-- 180秒,也就是3分鍾 -->
  <property name="removeAbandonedTimeout" value="180" /> <!-- 世界設置小 3分鍾sleep 直接強制關閉 -->
  <!-- 關閉abanded連接時輸出錯誤日志 -->
  <property name="logAbandoned" value="true" />

  關聯hibernate 配置中

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect"> ${hibernate.dialect} </prop>
				<prop key="hibernate.show_sql"> ${hibernate.show_sql} </prop>
				<prop key="hibernate.jdbc.fetch_size"> ${hibernate.jdbc.fetch_size} </prop>
				<prop key="hibernate.jdbc.batch_size"> ${hibernate.jdbc.batch_size} </prop>
				<prop key="hibernate.format_sql"> ${hibernate.format_sql} </prop>
				<prop key="hibernate.c3p0.max_statements"> ${hibernate.c3p0.max_statements} </prop>
        		<prop key="hibernate.hbm2ddl.auto">none</prop>
        		<prop key="hibernate.connection.release_mode">after_transaction</prop>
			</props>
		</property>

 屬性  key="hibernate.connection.release_mode" 這一列要填 after_transaction, 如果是auto也會很有可能初戀數據庫連接一直活躍被占用

好了,這幾個地方注意下,基本上是可以解決問題的

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM