c3p0原始碼分析

handawei_5發表於2010-04-23

資料庫連線池基礎

·     沒有連線池的資料庫連線方式指通過DriverManager和基本實現DataSource進行連線,但它相關連線的建立以及關閉是非常耗時的.

·     如果使用連線池,將有池來管理相關的資料庫連線,減少對資料庫連線操作.

·     連線池所做的操作,除了管理連線,還有就是對資料庫jdbc api的封裝,但jdbc api才是根本,外面做的都是包裝,再花哨都是假的。

 c3p0統一概念

  checkout == 從池中取得可用的連線
   checkoutconnection ==
被使用的連線
   checkin  ==
把連線放回池中
   checkinconnection ==
沒有被使用的連線
  
所有超時設定,相關的連線,是物理連線的關閉,而不是連線返回池中
  
管理的是pooledconnection,而不是物理的connection
   pooledconnectionsun針對連線池的介面,它本身包含connection,和這個connection相關的所有statement,result,一個checkoutconnection所作的所有資料庫操作,都被pooledconnection所管理.
   statement
快取,主要針對PreparedStatementCallableStatement,statment快取主要相對一個connection來說的,不同connectionstatment不能通用

c3p0行為

生成一個connnection

·     當池中connection沒有到達最大數,當有請求出現,將會產生connection.

·     成生一個pooledconnection

·     通過pooledconnection.getConnection()得到連線(得到連線是newProxyConnection,不是物理連線)

 checkin connection

·     pooledconnection脫離關係

·     關閉與這個connection相關的resultset

·     關閉所有沒有緩衝的statement.

·     checkin所有快取的statement.

·     修改pooledconnection相關資訊

 checkout connection 

·     檢視池中是否有沒有使用的connection,有就返回

·     沒有,如果沒有達到最大數,就生成一個,或者就等待

 

omcc3p0常用配置屬性


automaticTestTable


automaticTestTable
作為測試connection是否有效的表,如果表存在,但有記錄,丟擲錯誤,如果表不存在,則建立,並使用 SELECT * FROM automaticTestTable 作為連線測試語句

如果automaticTestTable沒有設定,而preferredTestQuery設定,則使用preferredTestQuery作為連線測試語句

checkoutTimeout

從池中拿未使用的連線,超時設定,如果沒有設定,就不超時.

numConnections

表明池中有多少個連線

numIdleConnections

表明池中有多少個空閒連線,它們可以被checkout

numBusyConnections

表明池中有多少個被checkout的連線,記住:numIdleConnections + numBusyConnections == numConnections

numUnclosedOrphanedConnections

都是checkoutconnection,但他們已經不再池中管理了.當他們checkin時候,將被destory

 

connectionCustomizerClassName


hook
方法,在對相關資源做操作的時候,''他所操作的connection是真實的資料庫連線,而不是proxy過的connection''

 

maxIdleTime
checkout一個connection時候,判斷這個connection沒有被使用的時間是否大於maxIdleTime,來決定是關閉它,還是被checkout
maxConnectionAge

設定一個連線在池中最長的時間,如果時間超過,將會從池中清除

testConnectionOnCheckout
如果設定為true,每次從池中取一個連線,將做一下測試,使用automaticTestTable 或者 preferredTestQuery,做一條查詢語句.看看連線好不好用,不好用,就關閉它,重新從池中拿一個.
unreturnedConnectionTimeout

一個checkout連線的超時設定,一旦一個checkout連線超時,他將物理的關閉,而不是返回池中,主要是防止連線被長期使用不釋放,這個設定也是比較危險的
idleConnectionTestPeriod
設定在池中的沒有被使用的連線,是否定時做測試,看看這個連線還可以用嗎?
maxStatements,maxStatementsPerConnection
快取statement,一個全域性的,一個是針對每一個connection,個人覺得效果不是很大,而且也使用了反射機制.
c3p0 jconsole說明

·          sampleThreadPoolStackTraces:列印出當前c3p0執行緒池的情況,預設是3個執行緒,c3p0很多行為非同步,放到執行緒中做的,比如checkout,checkin,close操作,還有內部池重新整理

·          sampleThreadPoolStatus:列印出當前c3p0執行緒池堆疊

·          softResetDefaultUser:關閉所有checkinconnection,重新初始化池

·          hardReset:關閉所有checkinconnectioncheckoutconnection,池這個物件也不要了,全是新的.

·          close:關閉所有跟c3p0相關的東西

 

原始碼分析

生成eclipse專案

·          sourceforge下載我們目前使用的0.9.1.2版本 [http://nchc.dl.sourceforge.net/sourceforge/c3p0/c3p0-0.9.1.2.src.zip 下載]

·          ant codegen(因為它有很自動生成程式碼)

·          匯入eclipse(source包括src/classes,build/codegen,缺少juit.jar,log4j.jar,自己解決)

相關概念

首先對datasource的理解,你可以把認為是factory,這樣會好理解一點

·          PooledDataSource
 
預設情況情況下,PooledDataSource只管理一個連線池(getConnection()的時候),如果你使用getConnection(username,password),而不是預設的username,
 
將會再生產一個連線池針對這個特定的使用者,它包含一個ConnectionPoolDataSource實現,連線就是從ConnectionPoolDataSource得到的.

·          ConnectionPoolDataSource
 
包名是javax.sql,一看就知道是sun定製的介面,表現出一個連線池,PooledConnection的工廠

·          PooledConnection
 
包名是javax.sql,也是sun定製的介面.c3p0預設的實現是NewPooledConnection

·          Connection,Statement,Result
 
運算元據庫相關介面,在c3p0中對於NewProxyConnection,NewProxyStatement,NewProxyResultSet,這些東西統一被PooledConnection管理。

c3p0專案情況
c3p0
是現在用的最多連線池之一,這麼成功的專案卻只是一個人開發的。

當目標很明確(連線池要做什麼,目標是非常明確的),使用場景很普通的時候,專案能成功,完全求決於程式的架構.

專案在jmx管理和本身死鎖監測,做的都比較精彩,但也有它不足支援,jdk1.5提供了很多功能(比如多執行緒),它很多都是自己實現了,這就要看作者怎麼對待這個專案

目前給我的感覺有點象當年的dom4j感覺,畢竟都需要謀生,創作激情會下降的.

相關文章