【數據庫】連接池的作用

        文章轉載:原文地址不詳,原作者有。。。可聯繫!

連接池是創建和管理多個連接的一種技術,這些連接可被需要使用它們的任何線程使用。連接池技術基於下述事實:對於大多數應用程序,當它們正在處理通常需要數毫秒完成的事務時,僅需要能夠訪問JDBC連接的1個線程。未處理事務時,連接處於閒置狀態。使用連接池,允許其他線程使用閒置連接來執行有用的任務。事實上,當某一線程需要用JDBC在MySQL或其他數據庫上執行操作時,需要用到由連接池提供的連接。使用連接完成線程後,線程會將連接返回給連接池,以便該連接能夠被其他需要使用連接的線程使用。從連接池“借出”連接時,該連接僅供請求它的線程使用。從編程觀點看,其效果等同於每次需要JDBC連接時調用DriverManager.getConnection(),但是,採用連接池技術,可通過使用新的或已有的連接結束線程。連接池技術能顯著增加Java應用程序的性能,同時還能降低資源使用率。

連接池技術的主要優點包括:

(1) 縮短了連接創建時間

        創建新的JDBC連接會導致聯網操作和一定的JDBC驅動開銷,如果這類連接是“循環”使用的,使用該方式,可避免這類不利因素。

(2)簡化的編程模型

        使用連接池技術時,每個單獨線程能夠像創建了自己的JDBC連接那樣進行操作,從而允許使用直接的JDBC編程技術。

(3)受控的資源使用

        如果不使用連接池技術,而是在每次需要時爲線程創建新的連接,那麼應用程序的資源使用將十分浪費,而且在負載較重的情況下會導致無法預期的結果。

注意,與數據庫的每個連接均會在客戶端和服務器端造成一定的開銷(CPU、關聯轉換等)。每個連接均會對應用程序和數據庫服務器的可用資源帶來一定的限制。無論連接是否執行任何有用的任務,仍將使用這些資源中的相當一部分。

        連接池能夠使性能最大化,同時還能將資源利用控制在一定的水平之下,如果超過該水平,應用程序將崩潰而不僅僅是變慢。

        幸運的是,Sun公司通過JDBC-2.0“可選”接口,完成了JDBC中連接池概念的標準化實施,所有主要應用服務器均實施了能夠與mysql Connector/J一起良好工作的這類API。

通常,你可以在應用服務器的配置文件中配置連接池,並通過Java命名和目錄接口(JNDI)訪問它。使用連接池時需要牢記的最重要事項是,無論在代碼中出現了什麼(異常、控制流等),連接以及由連接創建的任何部分(語句、結果集等)均應被關閉,以便能再次使用它們。如不然,它們將糾纏在一起,在最好的情況下,意味着它們所代表的數據庫服務器資源(緩衝區、鎖定、套接字等)可能會捆綁一段時間,在最壞的情況下,可能會導致永久捆綁。

連接池的最佳大小是什麼?

        取決於具體情況。儘管最佳大小取決與預期的負載和平均的數據庫事務時間,最佳的連接池大小小於你的預期。例如,如果使用的是Sun公司的Java Petstore Blueprint應用程序,對於包含15~20個連接的連接池,使用MySQL和Tomcat,在可接受的相應時間下,可服務於中等程度的負載(600個併發用戶)。要想確定用於應用程序的連接池大小,應使用諸如Apache Jmeter或The Grinder等工具創建負載測試腳本,並對應用程序進行負載測試。確定出發點的一種簡單方法是,將連接池的最大連接數配置爲“無限”,運行負載測試,並測量最大的併發連接數。隨後,應進行反向操作,確定出使應用程序具有最佳性能的連接池的最小和最大值。

連接池與數據源區別?

        數據庫連接池是在應用程序啓動時建立足夠的數據庫連接,並將這些連接組成一個連接池,由應用程序動態地對池中的連接進行申請、使用和釋放。對於多於連接池中連接數的併發請求,應在請求隊列中排隊等待。並且應用程序可根據池中連接的使用率,動態增加或減少池中的連接數。當關閉連接操作時,連接並不真正的關閉,而是返回到連接池中作爲空閒連接在後面繼續使用,連接池技術解決了數據庫連接頻繁打開關閉所帶來的性能問題。

        有了連接池,我們沒必要直接找數據源打交道了,連接池在你的程序所在的機器內存,數據源不一定,並且數據源和連接池會保持一定數量的連接,這樣我們訪問數據庫的時候就不需要找數據源要連接,直接在本地內存中取得連接,可以提高程序的性能。連結池的存在是爲了效率,因爲實例化一個連接很耗費資源,而連接又有可重用的特徵,所以可以把一定數量的連接放在連接池裏面以提高效率。

        下面是詳細的配置:
tomcat中配置數據庫連接池

[html] view plain copy
  1. <Resource        
  2.     name="jdbc/test"        
  3.     auth="Container"        
  4.     factory="org.apache.naming.factory.BeanFactory"        
  5.     type="com.mchange.v2.c3p0.ComboPooledDataSource"        
  6.     description="DB Connection"        
  7.     driverClass="oracle.jdbc.driver.OracleDriver"   
  8.     user="root"    
  9.     password="123456"    
  10.     jdbcUrl="jdbc:oracle:thin:@127.0.0.1:1521:orcl"         
  11.     maxPoolSize="4"        
  12.     minPoolSize="2"        
  13.     acquireIncrement="1"       
  14. />   

1、proxool連接池
在WEB-INF/classes/下建立文件:Proxool.properties
文件內容如下:

[html] view plain copy
  1. proxool.alias=test  
  2. proxool.driver-class=oracle.jdbc.driver.OracleDriver  
  3. proxool.driver-url=jdbc:oracle:thin:@127.0.0.1:1521:orcl  
  4. user=root  
  5. password=123456  
  6. proxool.maximum-connection-count=20  
  7. proxool.prototype-count=4  
  8. proxool.house-keeping-test-sql=select sysdate from DUAL  
  9. proxool.verbose=true  
  10. proxool.statistics=10s,1m,1d  

在web.xml文件內加入以下內容:

[html] view plain copy
  1. <servlet>   
  2.     <servlet-name>ServletConfigurator</servlet-name>   
  3.     <servlet-class>  
[html] view plain copy
  1. org.logicalcobwebs.proxool.configuration.ServletConfigurator  
[html] view plain copy
  1.     </servlet-class>  
  2.     <init-param>   
  3.         <param-name>propertyFile</param-name>   
  4.         <param-value>WEB-INF/classes/Proxool.properties</param-value>   
  5.     </init-param>   
  6.     <load-on-startup>1</load-on-startup>   
  7. </servlet>   

2、tomcat默認的連接池

[html] view plain copy
  1. <Resource   
  2.  name="jdbc/test"   
  3.  auth="Container"   
  4.  type="javax.sql.DataSource"  
  5.  driverClassName="oracle.jdbc.driver.OracleDriver"   
  6.  url="jdbc:oracle:thin:@127.0.0.1:1521:orcl"  
  7.  username="root"   
  8.  password="123456"   
  9.  maxActive="30"   
  10.  maxIdle="15"   
  11.  maxWait="-1"   
  12.  validationQuery="select 1 from dual"  
  13. />  


spring中的配置:
1 proxool的配置

[html] view plain copy
  1. <bean id="proxoolDataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource">  
  2.  <property name="driver" value="${jdbc.connection.driverClassName}"/>   
  3.  <property name="driverUrl" value="${jdbc.connection.url}"/>   
  4.  <property name="user" value="${jdbc.connection.username}"/>   
  5.  <property name="password" value="${jdbc.connection.password}"/> <!-- 測試的SQL執行語句 -->  
  6.  <property name="houseKeepingTestSql" value="${proxool.houseKeepingTestSql}"/> <!-- 最少保持的空閒連接數 默認2個 -->  
  7.   <property name="prototypeCount" value="${proxool.prototypeCount}"/> <!-- proxool自動偵察各個連接狀態的時間間隔(毫秒),偵察到空閒的連接就馬上回收,超時的銷燬 默認30秒 -->  
  8.   <property name="houseKeepingSleepTime" value="${proxool.hourseKeepingSleepTime}"/> <!-- 最大活動時間(超過此時間線程將被kill,默認爲5分鐘) -->  
  9.   <property name="maximumActiveTime" value="${proxool.maximumActiveTime}"/> <!-- 連接最長時間(默認爲4個小時) -->  
  10.   <property name="maximumConnectionLifetime" value="${proxool.maximumConnectionLifetime}"/> <!-- 最小連接數 默認2個 -->  
  11.   <property name="minimumConnectionCount" value="${proxool.minimumConnectionCount}"/> <!-- 最大連接數 默認5個 -->  
  12.   <property name="maximumConnectionCount" value="${proxool.maximumConnectionCount}"/> <!-- -->  
  13.   <property name="statistics" value="${proxool.statistics}"/> <!-- 別名 -->   
  14.   <property name="alias" value="${proxool.alias}"/> <!-- -->   
  15.   <property name="simultaneousBuildThrottle" value="${proxool.simultaneous-build-throttle}"/>  
  16. </bean>  

然後注入到sessionFactory中 
 

[html] view plain copy
  1. <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
  2.   <property name="dataSource" ref="proxoolDataSource"/>   
  3. </bean>    


 
 
Porxool 配置文件

[html] view plain copy
  1. <proxool.xml>  
  2. <?xml version="1.0" encoding="UTF-8"?>   
  3.  <proxool> <alias>orcl</alias>   
  4.   <driver-url>jdbc:oracle:thin:@127.0.0.1:1521:orcl</driver-url>   
  5.   <driver-class>oracle.jdbc.driver.OracleDriver</driver-class>   
  6.   <driver-properties>   
  7.    <property name="user" value="root" />   
  8.    <property name="password" value="123456" />   
  9.   </driver-properties>   
  10.   <minimum-connection-count>2</minimum-connection-count>   
  11.   <maximum-connection-count>40</maximum-connection-count>   
  12.   <simultaneous-build-throttle>20</simultaneous-build-throttle>   
  13.   <prototype-count>2</prototype-count>   
  14.   <house-keeping-test-sql>select CURRENT_DATE</house-keeping-test-sql>   
  15.  </proxool>   


 
配置說明 
alias -〉數據庫連接別名程序中需要使用的名稱
driver-url -〉數據庫驅動 
driver-class -〉驅動程序類 
driver-properties -〉聯機數據庫的用戶和密碼 
minimum-connection-count -〉最小連接數量建議設置0以上保證第一次連接時間 
maximum-connection-count -〉最大連接數量如果超過最大連接數量則會拋出異常。連接數設置過多服務器CPU和內存性能消耗很 大。 
simultaneous-build-throttle -〉同時最大連接數 
prototype-count -〉一次產生連接的數量。 例如果現在prototype-count設置爲4個但是現在已經有2個可以獲得的連接那麼 將會試圖再創建2個連接。 但不能超過最大連接數。
maximum-active-time -〉連接最大時間活動 默認5分鐘 
maximum-connection-lifetime -〉連接最大生命時間 默認4小時


<!-- 定義數據源Bean,使用C3P0數據源實現-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <!-- 指定連接數據庫的驅動-->
        <property name="driverClass" value="Oracle.jdbc.driver.OracleDriver"/>
        <!-- 指定連接數據庫的URL-->
        <property name="jdbcUrl" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/>
        <!-- 指定連接數據庫的用戶名-->
        <property name="user" value="root"/>
        <!-- 指定連接數據庫的密碼-->
        <property name="password" value="123456"/>
        <!-- 指定連接池中保留的最大連接數. Default:15-->
        <property name="maxPoolSize" value="15"/>
        <!-- 指定連接池中保留的最小連接數-->
        <property name="minPoolSize" value="10"/>
        <!-- 指定連接池的初始化連接數  取值應在minPoolSize 與 maxPoolSize 之間.Default:3-->
        <property name="initialPoolSize" value="5"/>
        <!-- 最大空閒時間,60秒內未使用則連接被丟棄。若爲0則永不丟棄。 Default:0-->
        <property name="maxIdleTime" value="60"/>
        <!-- 當連接池中的連接耗盡的時候c3p0一次同時獲取的連接數. Default:3-->
        <property name="acquireIncrement" value="5"/>
        <!-- JDBC的標準,用以控制數據源內加載的PreparedStatements數量。但由於預緩存的statements屬於單個connection而不是整個連接池所以設置這個參數需要考慮到多方面的因數.如果maxStatements與maxStatementsPerConnection均爲0,則緩存被關閉。Default:0-->
        <property name="maxStatements" value="0"/>
        <!-- 每60秒檢查所有連接池中的空閒連接.Default:0 -->
        <property name="idleConnectionTestPeriod" value="60"/>
        <!-- 定義在從數據庫獲取新連接失敗後重復嘗試的次數。 Default:30 -->
        <property name="acquireRetryAttempts" value="30"/>
        <!-- 獲取連接失敗將會引起所有等待連接池來獲取連接的線程拋出異常。但是數據源仍有效保留,並在下次調用getConnection()的時候繼續嘗試獲取連接。如果設爲true,那麼在嘗試獲取連接失敗後該數據源將申明已斷開並永久關閉。Default:false -->
        <property name="breakAfterAcquireFailure" value="true"/>
        <!-- 銀性能消耗大請只在需要的時候是喲個它。如果設爲true,那麼在每個connection提交的時候都將校驗其有效性。建議使用idleConnectionTestPeriod或automaticTestTable等提升連接測試的性能。 Default:false-->
        <property name="testConnectionOnCheckout" value="false"/>
</bean>
    
hibernate的配置:
1 只需在hibernate.cfg.xml中加入

[html] view plain copy
  1. <property name="connection.username">root</property>  
  2. <property name="connection.password">123456</property>   
  3. <property name="connection.url">jdbc:oracle:thin:@127.0.0.1:1521:orcl</property>   
  4. <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>  
  5. <property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>   
  6. <property name="format_sql">true</property>  
  7. <property name="show_sql">true</property>   
  8. <property name="myeclipse.connection.profile">oracle10g_112</property>    
  9. <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider </property>  
  10. <property name="hibernate.c3p0.min_size">5</property> //連接池中數據庫連接的最小數目   
  11. <property name="hibernate.c3p0.max_size">30</property>  //連接池中數據庫連接的最大數目   
  12. <property name="hibernate.c3p0.time_out">1800</property> //設定數據庫連接的過期時間,以秒爲單位   
  13. <property name="hibernate.c3p0.max_statement">50</property> //可以被緩存的PreparedStatement實例的最大數目。緩存適量的PreparedStatement實例,能夠大大提高Hibernate的性能。  
  14. <property name="hibernate.c3p0.idle_test_period">120</property>//在使數據庫連接自動生效之前處於空閒狀態的時間,以秒爲單位  
  15. <property name="hibernate.c3p0.acquire_increment">2</property>  
[html] view plain copy
  1.   

還有在classespath中加入c3p0-0.8.4.5.jar   

2 dbcp(hibernate3.0 已經不支持dbcp)    
在hibernate.cfg.xml中加入  

[html] view plain copy
  1. <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>  
  2. <property name="connection.url"> jdbc:oracle:thin:@127.0.0.1:1521:orcl</property>  
  3. <property name="connection.username">root</property>   
  4. <property name="connection.password">123456</property>    
  5. <property name="dbcp.maxActive">100</property>    
  6. <property name="dbcp.whenExhaustedAction">1</property>    
  7. <property name="dbcp.maxWait">60000</property>    
  8. <property name="dbcp.maxIdle">10</property>     
  9. <property name="dbcp.ps.maxActive">100</property>    
  10. <property name="dbcp.ps.whenExhaustedAction">1</property>    
  11. <property name="dbcp.ps.maxWait">60000</property>    
  12. <property name="dbcp.ps.maxIdle">10</property>      

 還有在classespath中加入commons-pool-1.2.jar 和commons-dbcp-1.2.1.jar.  
 
3 proxool (有問題,暫時不可用)  
在hibernate.cfg.xml中加入: 
<property name="dialect">org.hibernate.dialect.Oracle9Dialect </property> 
<property name="format_sql">true</property>
<property name="show_sql">true</property> 
<property name="myeclipse.connection.profile">oracle10g_112 </property> <!-- 配置proxool數據庫連接池 --> <!-- 連接池的別名 -->
<property name="hibernate.proxool.pool_alias">Proxool_DB_Pool</property>  <!-- 向Hibernate聲明連接池的配置文件位置(和hibernate.cfg.xml放在一個目錄下) -->
<property name="hibernate.proxool.xml">ProxoolConf.xml</property>  <!-- 定義Hibernate的連接加載類,這裏Proxool連接池是用這個,不同的連接池有不同的加載類 -->
<property name="hibernate.connection.provider_class"> org.hibernate.connection.ProxoolConnectionProvider </property> <!--爲false,當hibernate開始被調用時,就會初始化proxool連接池,進行數據庫連接等操作  -->
<property name="hibernate.proxool.existing_pool">true</property> 

在和hibernate.cfg.xml同一個目錄下,加一個ProxoolConf.xml文件,
內容爲<?xml version="1.0" encoding="UTF-8"?> 
<something-else-entirely>  
<proxool>   
<!-- 連接池別名 -->
<alias>Proxool_DB_Pool</alias>    
<!--proxool只能管理由自己產生的連接--> 
<driver-url>jdbc:oracle:thin:@10.142.50.112:1521:omds</driver-url>    
<driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
<driver-properties>    
  <property name="user" value="omdssd_admin"/>
  <property name="password" value="omdssd_hskj"/> 
</driver-properties>    
<!-- proxool自動偵察各個連接狀態的時間間隔(毫秒),偵察到空閒的連接就馬上回收,超時的銷燬-->    
<house-keeping-sleep-time>90000</house-keeping-sleep-time>    
<!-- 指因未有空閒連接可以分配而在隊列中等候的最大請求數,超過這個請求數的用戶連接就不會被接受-->    
<maximum-new-connections>20</maximum-new-connections>
<!-- 最少保持的空閒連接數-->    
<prototype-count>5</prototype-count>    
<!-- 允許最大連接數,超過了這個連接,再有請求時,就排在隊列中等候,最大的等待請求數由maximum-new-connections決定-->    
<maximum-connection-count>100</maximum-connection-count>  
<!-- 最小連接數-->    
<minimum-connection-count>10</minimum-connection-count>   
</proxool>  
</something-else-entirely>    
並在classespath中加入proxool-0.8.3.jar

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章