C3P0 代码分析
數據庫連接池基礎
·?????沒有連接池的數據庫連接方式指通過DriverManager和基本實現DataSource進行連接,但它相關連接的建立以及關閉是非常耗時的.
·?????如果使用連接池,將有池來管理相關的數據庫連接,減少對數據庫連接操作.
·?????連接池所做的操作,除了管理連接,還有就是對數據庫jdbc api的封裝,但jdbc api才是根本,外面做的都是包裝,再花哨都是假的。
?c3p0統一概念
? checkout ==?從池中取得可用的連接
?? checkoutconnection ==?被使用的連接
?? checkin? ==?把連接放回池中
?? checkinconnection ==?沒有被使用的連接
???所有超時設置,相關的連接,是物理連接的關閉,而不是連接返回池中
???管理的是pooledconnection,而不是物理的connection
?? pooledconnection是sun針對連接池的接口,它本身包含connection,和這個connection相關的所有statement,result,一個checkout的connection所作的所有數據庫操作,都被pooledconnection所管理.
?? statement緩存,主要針對PreparedStatement和CallableStatement,statment緩存主要相對一個connection來說的,不同connection的statment不能通用.?
c3p0行為
生成一個connnection
·?????當池中connection沒有到達最大數,當有請求出現,將會產生connection.
·?????成生一個pooledconnection
·?????通過pooledconnection.getConnection()得到連接(得到連接是newProxyConnection,不是物理連接)
?checkin connection
·?????與pooledconnection脫離關系
·?????關閉與這個connection相關的resultset
·?????關閉所有沒有緩沖的statement.
·?????checkin所有緩存的statement.
·?????修改pooledconnection相關信息
?checkout connection?
·?????查看池中是否有沒有使用的connection,有就返回
·?????沒有,如果沒有達到最大數,就生成一個,或者就等待
?
omc中c3p0常用配置屬性
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:關閉所有checkinconnection和checkoutconnection,池這個對象也不要了,全是新的.
·??????????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感覺,畢竟都需要謀生,創作激情會下降的.
?
轉載于:https://www.cnblogs.com/wangbin/archive/2009/11/08/1598351.html
總結
- 上一篇: note-删除Visual Studio
- 下一篇: TechEd China 2009 课程