使用 APACHE COMMON DBCP +COMMON POOL+MYSQL串連無效的問題

來源:互聯網
上載者:User

使用 APACHE COMMON DBCP +COMMON POOL+MYSQL串連無效的問題

Throwable occurred: org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 50,123,505 milliseconds ago.  The last packet sent successfully to the server was 50,123,505 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.

這主要是由兩個原因引起來的:
1.mysql 會自動關閉長時間不用的connection,一個串連如果處於sleep狀態達到mysql的參數wait_timeout指定的時間(預設為8小時),就是自動關閉這個串連
2.common pool中沒有指定相應的串連檢查參數

解決辦法:從common pool的配置參數來解決:

 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  <property name="driverClassName">
   <value>${db.driver}</value>
  </property>
  <property name="url">
   <value>${db.url}</value>
  </property>
  <property name="username">
   <value>${db.user}</value>
  </property>
  <property name="password">
   <value>${db.password}</value>
  </property>
  <property name="maxActive">
   <value>100</value>
  </property>
  <property name="maxIdle">
   <value>50</value>
  </property>
  <property name="maxWait">
   <value>10000</value>
  </property>

  <property name="timeBetweenEvictionRunsMillis">
   <value>3600000</value><!--1 hours-->
  </property>
<!--
  <property name="minEvictableIdleTimeMillis">
   <value>20000</value>
  </property>
-->
  
  <property name="testWhileIdle">
   <value>true</value>
  </property>
  <property name="validationQuery">
   <value>select 1 from dual</value>
  </property>
 </bean>
使用上述的三個紅色的參數,就可以避免這個問題.這三個參數的意義:

timeBetweenEvictionRunsMillis:啟動connection校正定時器,定時器已耗用時間間隔就是timeBetweenEvictionRunsMillis的值.預設為-1,表示不啟動定時器,這裡設定為1小時,只要小於mysql的wait_timeout就可以了

testWhileIdle: true,表示檢查idle的connection,false為不檢查

validationQuery:用於檢查connection的sql語句.

這隻是一種方法,另外的幾種方法:

timeBetweenEvictionRunsMillis+minEvictableIdleTimeMillis:這種方式不檢查Connection的有效性,而是檢查串連的空閑時間,大於minEvictableIdleTimeMillis就清除.

  <property name="timeBetweenEvictionRunsMillis">
   <value>3600000</value><!--1 hours-->
  </property>

  <property name="minEvictableIdleTimeMillis">
   <value>120000</value><!--connection的空閑時間大於這個值,就直接被關閉,並從串連池中刪除-->
  </property>

如果不喜歡用定時器,也可以配置testOnBorrow+validationQuery參數:每次從串連池取參數都會校正串連的有效性.實際上這種方式效能會比定時器差些.
  <property name="testOnBorrow">
   <value>true</value>
  </property>
  <property name="validationQuery">
   <value>select 1 from dual</value>
  </property>

另外,也可以用testOnReturn+validationQuery,不過未必會解決問題:這表示每次使用完串連,歸還串連池的時候檢查串連的有效性,這有可能導致使用一次無效的串連,最好不要用.

上面的幾種方法可以合并使用,只是檢查的點多了,未必是好事.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.