c3p0,dbcp和proxool比較

c3p0,dbcp和proxool比較


不是的,這是三種數據源
我們知道jdbc可以連接數據庫,但是jdbc只封裝了一些crud語句,而真正和數據庫聯繫的數據源,java中jdbc默認綁定的數據源是odbc,比較垃圾的數據源
而上面三種數據源都是比較給力的,尤其是dbcp和c3p0,以後項目開發主要用這兩種數據源
而這三種數據源不是hibernate發明的,但是配置數據源在hibernate.cfg,xml裏沒錯!


現在常用的開源數據連接池主要有c3p0,dbcp和proxool三種,其中: 

hibernate開發組推薦使用c3p0;

spring開發組推薦使用dbcp (dbcp連接池有weblogic連接池同樣的問題,就是強行關閉連接或數據庫重啓後,無法reconnect ,告訴連接被重置,這

個設置可以解決); 

hibernate in action推薦使用c3p0和proxool;


下面具體就每種連接池的調研結果進行說明:

1. Apache-DBCP 
Ø BasicDataSource 相關的參數說明 


dataSource: 要連接的 datasource (通常我們不會定義在 server.xml) 
defaultAutoCommit: 對於事務是否 autoCommit, 默認值爲 true 
defaultReadOnly: 對於數據庫是否只能讀取, 默認值爲 false 
driverClassName:連接數據庫所用的 JDBC Driver Class, 
maxActive: 可以從對象池中取出的對象最大個數,爲0則表示沒有限制,默認爲8 
maxIdle: 最大等待連接中的數量,設 0 爲沒有限制(對象池中對象最大個數) 
minIdle:對象池中對象最小個數 
maxWait: 最大等待秒數, 單位爲 ms, 超過時間會丟出錯誤信息 
password: 登陸數據庫所用的密碼 
url: 連接數據庫的 URL 
username: 登陸數據庫所用的帳號 
validationQuery: 驗證連接是否成功, SQL SELECT 指令至少要返回一行 
removeAbandoned: 是否自我中斷, 默認是 false 
removeAbandonedTimeout: 幾秒後會自我中斷, removeAbandoned 必須爲 true 
logAbandoned: 是否記錄中斷事件, 默認爲 false 
minEvictableIdleTimeMillis:大於0 ,進行連接空閒時間判斷,或爲0,對空閒的連接不進行驗證;默認30分鐘 
timeBetweenEvictionRunsMillis:失效檢查線程運行時間間隔,如果小於等於0,不會啓動檢查線程,默認-1 
testOnBorrow:取得對象時是否進行驗證,檢查對象是否有效,默認爲false 
testOnReturn:返回對象時是否進行驗證,檢查對象是否有效,默認爲false 
testWhileIdle:空閒時是否進行驗證,檢查對象是否有效,默認爲false 
Ø 在使用DBCP的時候,如果使用默認值,則數據庫連接因爲某種原因斷掉後,再從連接池中取得連接又不進行驗證,這時取得的連接實際上就會是無效的數據庫連接。因此爲了防止獲得的數據庫連接失效,在使用的時候最好保證: 


username: 登陸數據庫所用的帳號 
validationQuery:SELECT COUNT(*) FROM DUAL 
testOnBorrow、testOnReturn、testWhileIdle:最好都設爲true 
minEvictableIdleTimeMillis:大於0 ,進行連接空閒時間判斷,或爲0,對空閒的連接不進行驗證 
timeBetweenEvictionRunsMillis:失效檢查線程運行時間間隔,如果小於等於0,不會啓動檢查線程 
Ø PS:在構造GenericObjectPool [BasicDataSource在其createDataSource () 方法中也會使用GenericObjectPool] 時,會生成一個內嵌類Evictor,實現自Runnable接口。如果timeBetweenEvictionRunsMillis大於0,每過timeBetweenEvictionRunsMillis毫秒Evictor會調用evict()方法,檢查對象的閒置時間是否大於 minEvictableIdleTimeMillis毫秒(_minEvictableIdleTimeMillis小於等於0時則忽略,默認爲30分鐘),是則銷燬此對象,否則就激活並校驗對象,然後調用ensureMinIdle方法檢查確保池中對象個數不小於_minIdle。在調用returnObject方法把對象放回對象池,首先檢查該對象是否有效,然後調用PoolableObjectFactory 的passivateObject方法使對象處於非活動狀態。再檢查對象池中對象個數是否小於maxIdle,是則可以把此對象放回對象池,否則銷燬此對象 


Ø 上述特性的可設置性已在代碼中驗證,具體性能是否能實現有待實際驗證 


2. C3P0 
Ø C3P0的官方example中使用的數據源爲ComboPooledDataSource,網上一篇文章詳細介紹了C3P0連接池配置中各項含義[這些配置項的含義在下載解壓c3p0的壓縮包之後目錄的doc\index.html中的Configuration部分也有詳細的介紹,這裏偷下懶:P],現摘錄如下: 


<c3p0-config> 
<default-config> 
<!--當連接池中的連接耗盡的時候c3p0一次同時獲取的連接數。Default: 3 --> 
<property name="acquireIncrement">3</property> 


<!--定義在從數據庫獲取新連接失敗後重復嘗試的次數。Default: 30 --> 
<property name="acquireRetryAttempts">30</property> 


<!--兩次連接中間隔時間,單位毫秒。Default: 1000 --> 
<property name="acquireRetryDelay">1000</property> 


<!--連接關閉時默認將所有未提交的操作回滾。Default: false --> 
<property name="autoCommitOnClose">false</property> 


<!--c3p0將建一張名爲Test的空表,並使用其自帶的查詢語句進行測試。如果定義了這個參數那麼 
屬性preferredTestQuery將被忽略。你不能在這張Test表上進行任何操作,它將只供c3p0測試 
使用。Default: null--> 
<property name="automaticTestTable">Test</property> 


<!--獲取連接失敗將會引起所有等待連接池來獲取連接的線程拋出異常。但是數據源仍有效 
保留,並在下次調用getConnection()的時候繼續嘗試獲取連接。如果設爲true,那麼在嘗試 
獲取連接失敗後該數據源將申明已斷開並永久關閉。Default: false--> 
<property name="breakAfterAcquireFailure">false</property> 


<!--當連接池用完時客戶端調用getConnection()後等待獲取新連接的時間,超時後將拋出 
SQLException,如設爲0則無限期等待。單位毫秒。Default: 0 --> 
<property name="checkoutTimeout">100</property> 


<!--通過實現ConnectionTester或QueryConnectionTester的類來測試連接。類名需制定全路徑。 
Default: com.mchange.v2.c3p0.impl.DefaultConnectionTester--> 
<property name="connectionTesterClassName"></property> 


<!--指定c3p0 libraries的路徑,如果(通常都是這樣)在本地即可獲得那麼無需設置,默認null即可 
Default: null--> 
<property name="factoryClassLocation">null</property> 


<!--Strongly disrecommended. Setting this to true may lead to subtle and bizarre bugs. 
(文檔原文)作者強烈建議不使用的一個屬性--> 
<property name="forceIgnoreUnresolvedTransactions">false</property> 


<!--每60秒檢查所有連接池中的空閒連接。Default: 0 --> 
<property name="idleConnectionTestPeriod">60</property> 


<!--初始化時獲取三個連接,取值應在minPoolSize與maxPoolSize之間。Default: 3 --> 
<property name="initialPoolSize">3</property> 


<!--最大空閒時間,60秒內未使用則連接被丟棄。若爲0則永不丟棄。Default: 0 --> 
<property name="maxIdleTime">60</property> 


<!--連接池中保留的最大連接數。Default: 15 --> 
<property name="maxPoolSize">15</property> 


<!--JDBC的標準參數,用以控制數據源內加載的PreparedStatements數量。但由於預緩存的statements 
屬於單個connection而不是整個連接池。所以設置這個參數需要考慮到多方面的因素。 
如果maxStatements與maxStatementsPerConnection均爲0,則緩存被關閉。Default: 0--> 
<property name="maxStatements">100</property> 


<!--maxStatementsPerConnection定義了連接池內單個連接所擁有的最大緩存statements數。Default: 0 --> 
<property name="maxStatementsPerConnection"></property> 


<!--c3p0是異步操作的,緩慢的JDBC操作通過幫助進程完成。擴展這些操作可以有效的提升性能 
通過多線程實現多個操作同時被執行。Default: 3--> 
<property name="numHelperThreads">3</property> 


<!--當用戶調用getConnection()時使root用戶成爲去獲取連接的用戶。主要用於連接池連接非c3p0 
的數據源時。Default: null--> 
<property name="overrideDefaultUser">root</property> 


<!--與overrideDefaultUser參數對應使用的一個參數。Default: null--> 
<property name="overrideDefaultPassword">password</property> 


<!--密碼。Default: null--> 
<property name="password"></property> 


<!--定義所有連接測試都執行的測試語句。在使用連接測試的情況下這個一顯著提高測試速度。注意: 
測試的表必須在初始數據源的時候就存在。Default: null--> 
<property name="preferredTestQuery">select id from test where id=1</property> 


<!--用戶修改系統配置參數執行前最多等待300秒。Default: 300 --> 
<property name="propertyCycle">300</property> 


<!--因性能消耗大請只在需要的時候使用它。如果設爲true那麼在每個connection提交的 
時候都將校驗其有效性。建議使用idleConnectionTestPeriod或automaticTestTable 
等方法來提升連接測試的性能。Default: false --> 
<property name="testConnectionOnCheckout">false</property> 


<!--如果設爲true那麼在取得連接的同時將校驗連接的有效性。Default: false --> 
<property name="testConnectionOnCheckin">true</property> 


<!--用戶名。Default: null--> 
<property name="user">root</property> 


<!--早期的c3p0版本對JDBC接口採用動態反射代理。在早期版本用途廣泛的情況下這個參數 
允許用戶恢復到動態反射代理以解決不穩定的故障。最新的非反射代理更快並且已經開始 
廣泛的被使用,所以這個參數未必有用。現在原先的動態反射與新的非反射代理同時受到 
支持,但今後可能的版本可能不支持動態反射代理。Default: false--> 
<property name="usesTraditionalReflectiveProxies">false</property> 


<property name="automaticTestTable">con_test</property> 
    <property name="checkoutTimeout">30000</property> 
    <property name="idleConnectionTestPeriod">30</property> 
    <property name="initialPoolSize">10</property> 
    <property name="maxIdleTime">30</property> 
    <property name="maxPoolSize">25</property> 
    <property name="minPoolSize">10</property> 
    <property name="maxStatements">0</property> 
    <user-overrides user="swaldman"> 
    </user-overrides> 
</default-config> 
<named-config name="dumbTestConfig"> 
    <property name="maxStatements">200</property> 
    <user-overrides user="poop"> 
      <property name="maxStatements">300</property> 
    </user-overrides> 
   </named-config> 
</c3p0-config> 


Ø 上述特性的可設置性已在代碼中驗證,具體性能是否能實現有待實際驗證 


Ø 從配置項的內容來看,C3P0和DBCP都有比較詳細的有關連接檢測保證的配置,我們可以看到C3P0可以控制數據源內加載的PreparedStatements數量,並且可以設置幫助線程的數量來提升JDBC操作的速度,這些是DBCP未提供的;另外從網絡上的評價來看,DBCP出現Bug的頻率要大於C3P0,不過這一點有待於我們自己實際的檢測。 


3. Proxool 
Ø Proxool的使用和dbcp以及c3p0稍有不同,我們需要並且只需要在使用基本的java.sql.DriverManager之前加載org.logicalcobwebs.proxool.ProxoolDriver驅動類,並且按照proxool定義的url格式 ["proxool." + alias + ":" + driverClass + ":" + driverUrl ,其中alias是爲連接池自定義的別名] 來獲得connection;具體的可以參看proxool doc下的UserGuide,或本文所附的示例代碼。下面對連接池的特性配置作詳細說明 [這個是自己翻譯的,不一定準確,有問題時請參看doc下的Properties ~]。 


n fatal-sql-exception 


以逗號隔開的異常列表,當設置了此項之後,每當出現SQLException時都將與列表中異常項作比較,如果匹配則認爲出現fatal異常,這將導致connection被丟棄,並且不論出現任何情況該異常將被重拋一次以通知用戶發生的情況。默認值爲null 


n fatal-sql-exception-wrapper-class 


如果配置了fatal-sql-exception,則默認的操作是丟棄引起SQLException的原因而只是拋出原始異常。使用fatal-sql-exception-wrapper-class這個特性可以將SQLException包裝到繼承SQLException或RunTimeException的任何異常類裏。Proxool提供了兩個類供使用FatalSQLException和FatalRunTimeException;使用這兩個類的話就將該選項設置爲'org.logicalcobwebs.proxool.FatalSQLException'或者'org.logicalcobwebs.proxool.FatalRuntimeException'。默認值爲null 


n house-keeping-sleep-time 


proxool自動偵察各個連接狀態的時間間隔(毫秒),偵察到空閒的連接就馬上回收,超時的銷燬,默認值爲30秒 


n house-keeping-test-sql 


如果偵察線程發現閒置連接,則會使用這個SQL語句來對這些連接進行檢查;這項設置的語句應該能夠被很快的執行,例如查詢當前時間 [info.setProperty("proxool.house-keeping-test-sql", "select CURRENT_DATE");] 。如果不設置則該選項被忽略 


n injectable-connection-interface、injectable-statement-interface、injectable-prepared-statement-interface、injectable-callable-statement-interface 


n jmx 


如果此項設爲true,則連接池將被以名稱"Proxool:type=Pool, name=<alias>"註冊爲JMS Server的MBean。默認值爲false 


n jmx-agent-id 


當且僅當jmx選項設爲true時使用,爲以逗號分隔的連接持註冊到的JMS代理名稱列表;如果不設置則所有註冊的JMX Server都將被使用 


n maximum-active-time 


線程最大存活時間,超過此時間的線程將被守護線程kill掉,默認值爲5分鐘 


n maximum-connection-count 


到數據庫的最大連接數,超過了這個連接,再有請求時,就排在隊列中等候,最大的等待請求數由simultaneous-build-throttle決定;默認值爲15 


n maximum-connection-lifetime 


連接最大存活時間,毫秒爲單位,默認值爲4小時 


n minimum-connection-count 


不管是否被使用都保持開放的最小連接數,默認值爲5 


n overload-without-refusal-lifetime 


用來判斷連接池狀態,如果在此選項設置時間內(毫秒爲單位)拒絕了連接,則認爲過負載。默認值爲60秒 


n prototype-count 


最少保持的空閒連接數,注意與minimum-connection-count區分。默認值爲0 


n simultaneous-build-throttle 


最大的等待請求數,默認值爲10 


n test-before-use 


如果設爲true則connection在使用前將以house-keeping-test-sql設置的語句測試,如果測試不通過則該connection被丟棄並會重新分配一個connection。默認爲false 


n test-after-use 


如果設爲true則connection在關閉(放回連接池)前將以house-keeping-test-sql設置的語句測試,如果測試不通過connection將被丟棄。默認值爲false 


Ø 與其它連接池特性的設置方法不同,Proxool不提供相應的set方法,所有特性都要以諸如info.setProperty("proxool.jmx", "false");方式設定 


Ø 上述特性的可設置性已在代碼中驗證,具體性能是否能實現有待實際驗證 


Ø Proxool與DBCP以及C3P0的性能比較,網上衆說紛紜,有待我們自己的測試;其中http://www.oioj.net/blog/user1/2853/archives/2006/298381.shtml 這篇文章對proxool和DBCP做了性能評測,其方法值得我們測試借鑑 




c3p0、dbcp和proxool比較


現在常用的開源數據連接池主要有c3p0、dbcp和proxool三種,其中: 
hibernate開發組推薦使用c3p0; 
spring開發組推薦使用dbcp(dbcp連接池有weblogic連接池同樣的問題,就是強行關閉連接或數據庫重啓後,無法reconnect,告訴連接被重置,這個設置可以解決); 
hibernate in action推薦使用c3p0和proxool;
dbcp所需jar:commons-dbcp.jar、commons-pool.jar
c3p0所需jar:c3p0-0.9.2.1.jar mchange-commons-java-0.2.3.4.jar


applicationContext.xml配置信息如下:

<!-- 配置dbcp數據源 -->
      <bean id="dataSource2" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <!-- 池啓動時創建的連接數量 -->
        <property name="initialSize" value="5"/>
        <!-- 同一時間可以從池分配的最多連接數量。設置爲0時表示無限制。 -->
        <property name="maxActive" value="30"/>
        <!-- 池裏不會被釋放的最多空閒連接數量。設置爲0時表示無限制。 -->
        <property name="maxIdle" value="20"/>
        <!-- 在不新建連接的條件下,池中保持空閒的最少連接數。 -->
        <property name="minIdle" value="3"/>
        <!-- 設置自動回收超時連接 -->  
        <property name="removeAbandoned" value="true" />
        <!-- 自動回收超時時間(以秒數爲單位) -->  
        <property name="removeAbandonedTimeout" value="200"/>
        <!-- 設置在自動回收超時連接的時候打印連接的超時錯誤  --> 
        <property name="logAbandoned" value="true"/>
        <!-- 等待超時以毫秒爲單位,在拋出異常之前,池等待連接被回收的最長時間(當沒有可用連接時)。設置爲-1表示無限等待。  -->  
        <property name="maxWait" value="100"/>  
      </bean>


      <!-- 配置c3p0數據源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <property name="jdbcUrl" value="${jdbc.url}" />
        <property name="driverClass" value="${jdbc.driverClassName}" />
        <property name="user" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <!--連接池中保留的最大連接數。Default: 15 -->
        <property name="maxPoolSize" value="100" />
        <!--連接池中保留的最小連接數。-->
        <property name="minPoolSize" value="1" />
        <!--初始化時獲取的連接數,取值應在minPoolSize與maxPoolSize之間。Default: 3 -->
        <property name="initialPoolSize" value="10" />
        <!--最大空閒時間,60秒內未使用則連接被丟棄。若爲0則永不丟棄。Default: 0 -->
        <property name="maxIdleTime" value="30" />
        <!--當連接池中的連接耗盡的時候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>



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