1. 程式人生 > >Java資料庫連線池比較(c3p0,dbcp,proxool和BoneCP)

Java資料庫連線池比較(c3p0,dbcp,proxool和BoneCP)

詳見:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp21

Java框架資料庫連線池比較(c3p0,dbcp和proxool,BoneC)
現在常用的開源資料連線池主要有c3p0,dbcp,proxool,BoneCP,其中:
¨         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的效能比較,網上眾說紛紜,有待我們自己的測試




總結spring下配置dbcp,c3p0,proxool資料來源連結池

applicationContext-datasource-jdbc.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC
    "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="no" default-lazy-init="true"
default-dependency-check="none">
<description>datasource</description>
<!--   
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
   <property name="driverClassName"><value>${jdbc.driverClassName}</value></property>
   <property name="url"><value>${jdbc.url}</value></property>
   <property name="username"><value>${jdbc.username}</value></property>
   <property name="password"><value>${jdbc.password}</value></property>
</bean>
-->

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"><value>${jdbc.driverClassName}</value></property>
    <property name="url"><value>${jdbc.url}</value></property>
    <property name="username"><value>${jdbc.username}</value></property>
    <property name="password"><value>${jdbc.password}</value></property>
    <property name="maxActive"><value>80</value></property> 
   <property name="maxIdle"><value>20</value></property> 
    <property name="maxWait"><value>3000</value></property> 
   
</bean>
<!--bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <property name="driverClass"><value>${jdbc.driverClassName}</value></property>
        <property name="jdbcUrl"><value>${jdbc.url}</value></property>
        <property name="user"><value>${jdbc.username}</value></property>
        <property name="password"><value>${jdbc.password}</value></property> 
        <property name="acquireIncrement"><value>5</value></property>
        <property name="idleConnectionTestPeriod"><value>3000</value></property>
        <property name="checkoutTimeout"><value>3000</value></property>
        <property name="maxPoolSize"><value>80</value></property>
        <property name="minPoolSize"><value>1</value></property>
        <property name="maxStatements"><value>6000</value></property>
        <property name="initialPoolSize"><value>5</value></property>
</bean-->

<!--
ComboPooledDataSource 引數說明
maxIdleTime:
最大空閒時間,60秒內未使用則連線被丟棄。若為0則永不丟棄。Default: 0
acquireIncrement:
當連線池中的連線耗盡的時候c3p0一次同時獲取的連線數。Default: 3
maxStatements:
JDBC的標準引數,用以控制資料來源內載入的PreparedStatements數量。但由於預快取的statements
屬於單個connection而不是整個連線池。所以設定這個引數需要考慮到多方面的因素。
如果maxStatements與maxStatementsPerConnection均為0,則快取被關閉。Default: 0
idleConnectionTestPeriod:
每60秒檢查所有連線池中的空閒連線。Default: 0
acquireRetryAttempts:
定義在從資料庫獲取新連線失敗後重復嘗試的次數。Default: 30
breakAfterAcquireFailure:
獲取連線失敗將會引起所有等待連線池來獲取連線的執行緒丟擲異常。但是資料來源仍有效
保留,並在下次呼叫getConnection()的時候繼續嘗試獲取連線。如果設為true,那麼在嘗試
獲取連線失敗後該資料來源將申明已斷開並永久關閉。Default: false
testConnectionOnCheckout:
因效能消耗大請只在需要的時候使用它。如果設為true那麼在每個connection提交的
時候都將校驗其有效性。建議使用idleConnectionTestPeriod或automaticTestTable
等方法來提升連線測試的效能。Default: false
-->
<!--bean id="dataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource">
   <property name="driver"><value>${jdbc.driverClassName}</value></property>
   <property name="driverUrl"><value>${jdbc.url}</value></property>
   <property name="user"><value>${jdbc.username}</value></property>
   <property name="password"><value>${jdbc.password}</value></property>
   <property name="alias"><value>test</value></property>
   <property name="houseKeepingSleepTime"><value>90000</value></property>
   <property name="prototypeCount"><value>10</value></property>
   <property name="maximumConnectionCount"><value>100</value></property>
   <property name="minimumConnectionCount"><value>10</value></property>
   <property name="trace"><value>true</value></property>
   <property name="verbose"><value>true</value></property>
</bean>
-->
</beans>
jdbc.properties

#jdbc.driverClassName=net.sourceforge.jtds.jdbc.Driver
#jdbc.url=jdbc:jtds:sybase://192.168.1.1:5000/test;charset=eucgb
#jdbc.username=yinxiao
#jdbc.password=yinxiao

#jdbc.driverClassName=org.hsqldb.jdbcDriver
#jdbc.url=jdbc:hsqldb:file:hsqldb/test
#jdbc.username=sa
#jdbc.password=

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?user=root&password=root&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8
jdbc.username=root
jdbc.password=root
#jdbc.url=jdbc:mysql://localhost:3306/test?user=root&amp;password=root&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;characterSetResults=UTF-8
#jdbc.driverClassName=net.sourceforge.jtds.jdbc.Driver
#jdbc.url=jdbc:jtds:sqlserver://localhost:1433/test;useUnicode=true&amp;characterEncoding=GBK&amp;characterSetResults=GBK
#jdbc.username=sa
#jdbc.password=sa
#jndi
jndi.factory.initial=weblogic.jndi.WLInitialContextFactory
jndi.provider.url=t3://127.0.0.1:7001
jndi.jndiName=jdbc/test

hibernate.properties

#hibernate.dialect=org.hibernate.dialect.SQLServerDialect
hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
#hibernate.dialect=org.hibernate.dialect.HSQLDialect
hibernate.cache.use_query_cache=true
#hibernate.cache.provider_class=net.sf.hibernate.cache.EhCacheProvider
hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
hibernate.show_sql=true
hibernate.format_sql=false
hibernate.transaction.auto_close_session=true
hibernate.connection.autocommit=false
hibernate.connection.isolation=2
hibernate.hbm2ddl.auto=update
hibernate.jdbc.fetch_size=50
hibernate.jdbc.batch_size=25
hibernate.default_batch_fetch_size=16
hibernate.transaction.factory_class=org.hibernate.transaction.JDBCTransactionFactory
#hibernate.transaction.factory_class=net.sf.hibernate.transaction.JDBCTransactionFactory
hibernate.query.factory_class=org.hibernate.hql.classic.ClassicQueryTranslatorFactory
hibernate.connection.release_mode=after_transaction
hibernate.cache.region_prefix=hibernate.cache.test
hibernate.default_schema=test




tomcat下配置資料庫連線池DBCP、C3P0、Proxool

1、將連線池的jar檔案拷貝到tomcat的lib目錄下
(1)dbcp:
tomcat預設包含tomcat-dbcp.jar,如果使用tomcat自帶的dbcp則不用拷貝jar檔案。
如果要使用commons-dbcp連線池,則要將commons-dbcp-xxx.jar和commons-pool.jar拷貝到tomcat的lib目錄下。
(2)c3p0:
拷貝c3p0-xx.jar到tomcat的lib目錄下
(3)proxool:
拷貝proxool-xx.jar、proxool-cglib.jar、commons-logging-xxx.jar到tomcat的lib目錄下
2、開啟tomcat的context.xml,進行如下配置:
<!--dbcp-->
<Resource
    name="jdbc/mysqlds-dbcp"
    auth="Container"
    type= "javax.sql.DataSource"
factory="org.apache.commons.dbcp.BasicDataSourceFactory"<!--這裡使用的commons-dbcp連線池-->
<!--tomcat的dbcp對應的factory為:將commons替換為tomcat,也可不用配置-->
    driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/test"
    username="root"
    password=""
    maxActive="100"
    maxIdle="30"
    maxWait="10000" >
</Resource>
   <!--c3p0-->
<Resource auth="Container"
     description="DB Connection"
     driverClass="com.mysql.jdbc.Driver"
     maxPoolSize="100"
     minPoolSize="2"
     acquireIncrement="2"
     name="jdbc/mysqlds-c3p0"
     user="root"
     password=""
     factory="org.apache.naming.factory.BeanFactory"
     type="com.mchange.v2.c3p0.ComboPooledDataSource"
     jdbcUrl="jdbc:mysql://localhost:3306/test" />
<!--proxool-->
<Resource name="jdbc/mysqlds-proxool"
     auth="Container"      
     type="javax.sql.DataSource"
     factory="org.logicalcobwebs.proxool.ProxoolDataSource"      
     proxool.alias="test"      
     user="root"    
     password=""      
     delegateProperties="foo=1,bar=true"
     proxool.jndi-name="mysqljndi"     
     proxool.driver-url="jdbc:mysql://127.0.0.1:3306/test"      
     proxool.driver-class="com.mysql.jdbc.Driver"    
     proxool.house-keeping-sleep-time="900000"    
     proxool.maximum-active-time="5"
     proxool.prototype-count="3"
     proxool.statistics="1m,15m,1d"
     proxool.simultaneous-build-throttle="10"
     proxool.minimum-connection-count="5"
     proxool.maximum-connection-count="15"   
/> 
3、在web.xml中配置如下程式碼:
<resource-ref>  
<res-ref-name>jdbc/mysqlds-proxool</res-ref-name>   <!--與context.xml下的Resources的name屬性一致-->
<res-type>javax.sql.DataSource</res-type>  
<res-auth>Container</res-auth>  
</resource-ref>
4、獲取連線java程式碼:
   Context context = new InitialContext();
    ds = (DataSource) context.lookup("java:/comp/env/jdbc/mysqlds-proxool");//與context.xml下的Resources的name屬性一致
5、常見問題:
      (1)create a new connection but it fail its test:
       在配置proxool連線池時,可能會包以上錯誤,可以看看你的context.xml配置,將
proxool.test-before-use="true"該行去掉即可,即在使用前不要進行測試




DBCP,C3P0,Proxool,BoneCP引數介紹

1 Apache-DBCP:
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
initialSize:初始化執行緒數


2 C3P0:
acquireIncrement: 當連線池中的連線耗盡的時候c3p0一次同時獲取的連線數。Default: 3
acquireRetryAttempts: 定義在從資料庫獲取新連線失敗後重復嘗試的次數。Default: 30
acquireRetryDelay: 兩次連線中間隔時間,單位毫秒。Default: 1000
autoCommitOnClose: 連線關閉時預設將所有未提交的操作回滾。Defaul t: false
automaticTestTable: c3p0將建一張名為Test的空表,並使用其自帶的查詢語句進行測試。如果定義了這個引數那麼屬性preferredTestQuery將被忽略。你不能在這張Test表上進行任何操作,它將只供c3p0測試使用。Default: null
breakAfterAcquireFailure: 獲取連線失敗將會引起所有等待連線池來獲取連線的執行緒丟擲異常。但是資料來源仍有效保留,並在下次呼叫getConnection()的時候繼續嘗試獲取連線。如果設為true,那麼在嘗試獲取連線失敗後該資料來源將申明已斷開並永久關閉。Default: false
checkoutTimeout:當連線池用完時客戶端呼叫getConnection()後等待獲取新連線的時間,超時後將丟擲SQLException,如設為0則無限期等待。單位毫秒。Default: 0
connectionTesterClassName: 通過實現ConnectionTester或QueryConnectionT ester的類來測試連線。類名需制定全路徑。Default: com.mchange.v2.c3p0.impl.Def aultConnectionTester
factoryClassLocation: 指定c3p0 libraries的路徑,如果(通常都是這樣)在本地即可獲得那麼無需設定,預設null即可Default: null
idleConnectionTestPeriod: 每60秒檢查所有連線池中的空閒連線。Defaul t: 0
initialPoolSize: 初始化時獲取三個連線,取值應在minPoolSize與maxPoolSize之間。Default: 3
maxIdleTime: 最大空閒時間,60秒內未使用則連線被丟棄。若為0則永不丟棄。Default: 0
maxPoolSize: 連線池中保留的最大連線數。Default: 15
maxStatements: JDBC的標準引數,用以控制資料來源內載入的PreparedSt atements數量。但由於預快取的statements屬於單個connection而不是整個連線池。所以設定這個引數需要考慮到多方面的因素。如果maxStatements與maxStatementsPerConnection均為0,則快取被關閉。Default: 0
maxStatementsPerConnection: maxStatementsPerConnection定義了連線池內單個連線所擁有的最大快取statements數。Default: 0
numHelperThreads:c3p0是非同步操作的,緩慢的JDBC操作通過幫助程序完成。擴充套件這些操作可以有效的提升效能通過多執行緒實現多個操作同時被執行。Default: 3
overrideDefaultUser:當用戶呼叫getConnection()時使root使用者成為去獲取連線的使用者。主要用於連線池連線非c3p0的資料來源時。Default: null
overrideDefaultPassword:與overrideDefaultUser引數對應使用的一個引數。Default: null
password:密碼。Default: null
user:使用者名稱。Default: null
preferredTestQuery:定義所有連線測試都執行的測試語句。在使用連線測試的情況下這個一顯著提高測試速度。注意:測試的表必須在初始資料來源的時候就存在。Default: null
propertyCycle:使用者修改系統配置引數執行前最多等待300秒。Defaul t: 300
testConnectionOnCheckout:因效能消耗大請只在需要的時候使用它。如果設為true那麼在每個connection提交的時候都將校驗其有效性。建議使用idleConnectio nTestPeriod或automaticTestTable等方法來提升連線測試的效能。Default: false
testConnectionOnCheckin:如果設為true那麼在取得連線的同時將校驗連線的有效性。Default: false


3 Proxool:

acquireIncrement: 當連線池中的連線耗盡的時候c3p0一次同時獲取的連線數。Default: 3
fatal-sql-exception : 它是一個逗號分割的資訊片段.當一個SQL異常發生時,他的異常資訊將與這個資訊片段進行比較.如果在片段中存在,那麼這個異常將被認為是個致命錯誤(Fatal SQL Exception ).這種情況下,資料庫連線將要被放棄.無論發生什麼,這個異常將會被重擲以提供給消費者.使用者最好自己配置一個不同的異常來丟擲.
fatal-sql-exception-wrapper-class : 正如上面所說,你最好配置一個不同的異常來重擲.利用這個屬性,使用者可以包裝SQLException,使他變成另外一個異常.這個異常或者繼承SQLException或者繼承字RuntimeException.proxool 自帶了2個實現:'org.logicalcobwebs.proxool .FatalSQLException' 和'org.logicalcobweb s.proxool .FatalRuntimeException' .後者更合適.
house-keeping-sleep-time : house keeper 保留執行緒處於睡眠狀態的最長時間,house keeper 的職責就是檢查各個連線的狀態,並判斷是否需要銷燬或者建立.
house-keeping-test-sql : 如果發現了空閒的資料庫連線.house keeper 將會用這個語句來測試.這個語句最好非常快的被執行.如果沒有定義,測試過程將會被忽略。
injectable-connection-interface : 允許proxool 實現被代理的connection物件法.
injectable-statement-interface : 允許proxool 實現被代理的Statement 物件方法.
injectable-prepared-statement-interface : 允許proxool 實現被代理的PreparedS tatement 物件方法.
injectable-callable-statement-interface : 允許proxool 實現被代理的CallableStat ement 物件方法.
jmx : 如果屬性為true,就會註冊一個訊息Bean到jms服務,訊息Bean物件名: "Proxool:type=Pool, name=<alias>". 預設值為false.
jmx-agent-id : 一個逗號分隔的JMX代理列表(如使用MbeanServerFactory .fi ndMBeanServer(String agentId)註冊的連線池。)這個屬性是僅當"jmx"屬性設定為"true"才有效。所有註冊jmx伺服器使用這個屬性是不確定的
jndi-name : 資料來源的名稱
maximum-active-time : 如果housekeeper 檢測到某個執行緒的活動時間大於這個數值.它將會殺掉這個執行緒.所以確認一下你的伺服器的頻寬.然後定一個合適的值.預設是5分鐘.
maximum-connection-count : 最大的資料庫連線數.
maximum-connection-lifetime : 一個執行緒的最大壽命.
minimum-connection-count : 最小的資料庫連線數
overload-without-refusal-lifetime : 這可以幫助我們確定連線池的狀態。如果我們已經拒絕了一個連線在這個設定值(毫秒),然後被認為是超載。預設為60秒。
prototype-count : 連線池中可用的連線數量.如果當前的連線池中的連線少於這個數值.新的連線將被建立(假設沒有超過最大可用數).例如.我們有3個活動連線2個可用連線,而我們的prototype-count是4,那麼資料庫連線池將試圖建立另外2個連線.這和 minimum-connection-count不同. minimum-connect ion-count把活動的連線也計算在內.prototype-count 是spare connections 的數量.
recently-started-threshold :這可以幫助我們確定連線池的狀態,連線數少還是多或超載。只要至少有一個連線已開始在此值(毫秒)內,或者有一些多餘的可用連線,那麼我們假設連線池是開啟的。預設為60秒
simultaneous-build-throttle :這是我們可一次建立的最大連線數。那就是新增的連線請求,但還沒有可供使用的連線。由於連線可以使用多執行緒,在有限的時間之間建立聯絡從而帶來可用連線,但是我們需要通過一些方式確認一些執行緒並不是立即響應連線請求的,預設是10。
statistics : 連線池使用狀況統計。 引數“10s,1m,1d”
statistics-log-level :日誌統計跟蹤型別。 引數“ERROR”或 “INFO”
test-before-use : 如果為true,在每個連線被測試前都會服務這個連線,如果一個連線失敗,那麼將被丟棄,另一個連線將會被處理,如果所有連線都失敗,一個新的連線將會被建立。否則將會丟擲一個SQLException異常。
test-after-use : 如果為true,在每個連線被測試後都會服務這個連線,使其回到連線池中,如果連線失敗,那麼將被廢棄。
trace : 如果為true,那麼每個被執行的SQL語句將會在執行期被log記錄(DEBUG LEVEL).你也可以註冊一個ConnectionListener (參看ProxoolFacade)得到這些資訊


4 BoneCP:

acquireIncrement: 當連線池中的連線耗盡的時候c3p0一次同時獲取的連線數。Default: 3
driveClass:資料庫驅動
jdbcUrl:響應驅動的jdbcUrl
username:資料庫的使用者名稱
password:資料庫的密碼
idleConnectionTestPeriod:檢查資料庫連線池中控線連線的間隔時間,單位是分,預設值:240,如果要取消則設定為0
idleMaxAge:連線池中未使用的連結最大存活時間,單位是分,預設值:60,如果要永遠存活設定為0
maxConnectionsPerPartition:每個分割槽最大的連線數
minConnectionsPerPartition:每個分割槽最小的連線數
partitionCount:分割槽數,預設值2,最小1,推薦3-4,視應用而定
acquireIncrement:每次去拿資料庫連線的時候一次性要拿幾個,預設值:2
statementsCacheSize:快取prepared statements的大小,預設值:0
releaseHelperThreads:每個分割槽釋放連結助理程序的數量,預設值:3,除非你的一個數據庫連線的時間內做了很多工作,不然過多的助理程序會影響你的效能

<bean id="mainDataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://127.0.0.1/yourdb" />
<property name="username" value="root"/>
<property name="password" value="abcdefgh"/>
<property name="idleConnectionTestPeriod" value="60"/>
<property name="idleMaxAge" value="240"/>
<property name="maxConnectionsPerPartition" value="30"/>
<property name="minConnectionsPerPartition" value="10"/>
<property name="partitionCount" value="3"/>
<property name="acquireIncrement" value="5"/>
<property name="statementsCacheSize" value="100"/>
<property name="releaseHelperThreads" value="3"/>
</bean>


1 c3p0、dbcp、proxool、BoneCP比較
1.1 測試環境:
作業系統:windows xp sp3
資料庫:mysql 5.1
1.2 測試條件:
initialSize=30;
maxSize=200;
minSize=30;
其餘引數為預設值;
1.3 測試程式碼:
利用JAVA程式碼模擬多執行緒對這三種資料庫連線池進行測試,通過花費的時間判斷效率
DBTest.java:
public class DBTest implements Runnable /*extends Thread*/ {
public long date1=0;
private static Proxool proxool;
public static int count = 0;
public static void main(String[] args) throws Exception {
//DBCP.init();
//C3P0.init();
//proxool = Proxool.getInstance();
BoneCPConn.init();
DBTest test = new DBTest();
test.startup();
}

public void startup() {
for (int i = 0; i <5; i++) {
Thread thread = new Thread(this);
thread.start();
}
}

public void run() {
if(date1==0)
{
date1 = System.currentTimeMillis();
System.out.println(date1);
}
for(int i=0 ; i<10 ; i++){
try {
//Connection conn = DBCP.getConnection();
// Connection conn = C3P0.getConnection();
//Connection conn =proxool.getConnection();
Connection conn = BoneCPConn.getConnection();
if (conn != null) {
Statement statement = conn.createStatement();
ResultSet rs = statement.executeQuery("select * from user where id=1");
while (rs.next()) {
String username = rs.getString(2);
System.out.println(username);
}
rs.close();
statement.close();
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
count++;
if(count==5)
{
long date2 = System.currentTimeMillis();
System.out.println(date2);
System.out.println("執行完畢!耗時為:" + (date2 - date1) + "ms");
}
}
}
4.3.1 模擬5個執行緒迴圈10次併發訪問資料庫
DBCP用時1181ms
C3P0用時860ms
Proxool用時1563ms
BoneCP用時31ms
4.3.2 模擬10個執行緒迴圈10次併發訪問資料庫
DBCP用時1188ms
C3P0用時953ms
Proxool用時1625ms
BoneCP用時63ms
4.3.3 模擬20個執行緒迴圈10次併發訪問資料庫
DBCP用時1204ms
C3P0用時1000ms
Proxool用時1640ms
BoneCP用時110ms
4.3.4 模擬30個執行緒迴圈10次併發訪問資料庫
DBCP用時1250ms
C3P0用時1047ms
Proxool用時1657ms
BoneCP用時156ms
4.3.5 模擬50個執行緒迴圈10次併發訪問資料庫
DBCP用時1406ms
C3P0用時1343ms
Proxool用時1843ms
BoneCP用時172ms
4.3.6 模擬100個執行緒迴圈10次併發訪問資料庫
DBCP用時1641ms
C3P0用時2703ms
Proxool用時2031ms
BoneCP用時532ms
4.3.7 模擬200個執行緒迴圈10次併發訪問資料庫
DBCP用時2093ms
C3P0用時4891ms
Proxool用時2406ms
BoneCP用時936ms
4.3.8 模擬500個執行緒迴圈10次併發訪問資料庫
DBCP用時3219ms
C3P0用時11703ms
Proxool用時3343ms
BoneCP用時1922ms
4.3.9 模擬800個執行緒迴圈10次併發訪問資料庫
DBCP用時4688ms
C3P0用時12063ms
Proxool用時4141ms
BoneCP用時2859ms
4.3.10 模擬1000個執行緒迴圈10次併發訪問資料庫
DBCP用時5187ms
C3P0用時12563ms
Proxool用時4703ms
BoneCP用時3610ms
4.3.11 模擬3000個執行緒迴圈10次併發訪問資料庫
DBCP用時14094ms
C3P0用時16297ms
Proxool用時11344ms
BoneCP用時11391ms
4.3.12 模擬5000個執行緒迴圈10次併發訪問資料庫
DBCP用時23610ms
C3P0用時22032ms
Proxool用時20125ms
BoneCP用時17125ms

4.4測試結果分析:
         BoneCP一直保持效能最佳
4.5 測試結論
          通過對四種資料庫連線池的效能測試發現,BoneCP的效能明顯優於其它三種.

相關推薦

Java資料庫連線比較c3p0,dbcp,proxoolBoneCP

詳見:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp21 Java框架資料庫連線池比較(c3p0,dbcp和proxool,BoneC) 現在常用的開源資料連線池主要有c3p0,dbcp,proxool

Java框架資料庫連線比較c3p0,dbcpproxool

現在常用的開源資料連線池主要有c3p0,dbcp和proxool三種,其中:  ¨         hibernate開發組推薦使用c3p0;  ¨         spring開發組推薦使用dbcp (dbcp連線池有weblogic連線池同樣的問題,就是強行關閉連

主流Java資料庫連線比較與開發配置實戰

1.資料庫連線池概述 資料庫連線的建立是一種耗時、效能低、代價高的操作,頻繁的資料庫連線的建立和關閉極大的影響了系統的效能。資料庫連線池是系統初始化過程中建立一定數量的資料庫連線放於連線池中,當程式需要訪問資料庫時,不再建立一個新的連線,而是從連線池中取出一個已建立的空

Java資料庫連線比較及使用場景

我們在連線資料庫的時候,由於建立資料庫連線代價很大(銷燬連線的代價也很大),需要消耗很多資源,因此引入資料庫連線池。資料庫連線池是一種池化技術,預先建立好資料庫連線,儲存在記憶體中,當需要連線時,從中取出即可,使用完後放回連線池。 下面我們介紹Java中常用的

Java資料庫連線比較

DBCP(DataBase connection pool)資料庫連線池。是Apache上的一個 java連線池專案,也是 tomcat使用的連線池元件。單獨使用dbcp需要3個包:common-dbcp.jar,common-pool.jar,common-collections.jar由於建立資料庫連線

Java資料庫連線的實現不用框架

前言:因為需要正式做專案,瞭解到了連線池這個東西。在網上找了很多資料,發現都是大同小異,各種轉載,看上去搜出來了幾十個答案,結果很可能是同一個。並且大多都是基於框架的資料庫連線池。可是我只是想採用MVC做一個不是很大的專案,不需要使用到框架啊。這可怎麼辦,最後沒

各種Java技術框架資料庫連線比較(一)

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

Java資料庫連線細節探討

我們知道,資料庫連線池可以把資料庫的連線快取起來,下次使用的話可以直接取到快取起來的資料庫連線。那麼,在這個過程中有幾個細節需要注意: 1、資料庫的連線數有沒有限制? 2、資料庫會不會自動斷開已經建立的連線? 3、如果資料庫重啟了,但應用沒有重啟,那麼資料庫連線池中的所有連線都不可用了,

HikariCP 的Java資料庫連線介紹及配置

HiKariCP是資料庫連線池的一個後起之秀,號稱效能最好,可以完美地PK掉其他連線池。 原文地址:http://blog.csdn.net/clementad/article/details/46928621 官網:https://github.com/brettwooldridge/Hi

Druid以及Druid常見的資料庫連線對比轉載

寫的灰常好非常細,關鍵是還有各種資料庫連線池的對比,條理比較清晰。 1. Druid是什麼? Druid是Java語言中最好的資料庫連線池。Druid能夠提供強大的監控和擴充套件功能。 2. 在哪裡下載druid 3. 怎麼獲取Druid的原始碼 Druid

Java資料庫連線

1.簡介 Java 獲取資料庫的基本方式有兩種:1,通過DriverManager;2,通過DataSource,這裡主要講述第二種。 1.1 DriverManager跟DataSource獲取getConnection 的區別 DriverManag

資料庫連線使用springboot

轉自:https://blog.csdn.net/u014209205/article/details/80625963 1. 為什麼要使用資料庫連線池         使用資料庫連線池主要考慮到程式與資料庫建立連線

為什麼HikariCP被號稱為效能最好的Java資料庫連線,如何配置使用

HiKariCP是資料庫連線池的一個後起之秀,號稱效能最好,可以完美地PK掉其他連線池。 什麼?不是有C3P0/DBCP這些成熟的資料庫連線池嗎?一直用的好好的,為什麼又搞出一個BoneCP來?因為,傳說中BoneCP在快速這個特點上做到了極致,官方資料是C3P0等

Java資料庫連線原理與簡易實現

1、什麼是資料庫連線池     我們現在在開發中一定都會用到資料庫,為了提高我們的系統的訪問速度,資料庫優化是一個有效的途徑。我們現在開發中使用資料庫一般都要經歷以下的四個步驟:(1)載入資料庫的驅動類,(2)建立資料庫連線,(3)進行資料操作,(4)關閉資料庫連線;在這四步中建立資料庫連線是一個比較耗時的操

java資料庫連線程式碼實現

import java.io.InputStream; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.uti

Java資料庫連線幾種方式及其特點

主流的資料庫連線池  在目前技術前沿比較流行的資料庫連線池有:DBCP、Tomcat Jdbc Pool、BoneCP、Druid、C3P0等 DBCP:由Apache開發的一個Java資料庫連線池專案, Jakarta commons-pool物件池機制,Tomcat使

java資料庫連線配置的幾種方法

一,Tomcat配置資料來源: 方式一:在WebRoot下面建資料夾META-INF,裡面建一個檔案context.xml,內容如下:  <Context>       <Resource name="jdbc/test" auth="Container" type="javax.sq

java資料庫連線proxool介紹及mysql8小時斷開連線問題的說明

Proxool是一種Java資料庫連線池技術。是sourceforge下的一個開源專案,這個專案提供一個健壯、易用的連線池, 最為關鍵的是這個連線池提供監控的功能,方便易用,便於發現連線洩漏的情況。 目前是和DBCP以及C3P0一起,最為常見的三種JDBC連線池技術。 日前

Spring+Hibernate的連線配置c3p0,proxool

本文所有的jar包都可以在我的資源裡下載 1、proxool 首先需要匯入jar包proxool-0.9.1.jar和proxool-cglib.jar; 建立proxool.xml,內容如下: <?xml version="1.0" encoding="utf-8"?

資料庫連線用法之(common-dbcp)

程式中如果想要用資料庫連線池。可以用commons-dbcp-1.4.jar。該jar會配合commons-pool-1.6.jar來使用。 具體來說明如何使用dbcp資料庫連線池。 1 建立一個數據源物件(需要引入:import org.apache.commons.db