摘要:該文介紹了基于JDBC的數據庫連接池的工作原理,提出了一個高效的連接管理策略,最后給出了數據庫應用的具體實現。
關鍵詞:JDBC;數據庫;數據庫連接池
中圖分類號:TP311.13 文獻標識碼:A 文章編號:1009-3044(2009)15-3859-02
Improvement and Application of Database Connection Pool Technology Based on JDBC
DAI Wei-wei
(Shao Xing Science and Artist School Computer Center,Shao Xing 312000, China)
Abstract: The article descrbs the working principle of database connection pool based on JDBC,Offers a high-efficient connection to manager the tactics in practical application. At last Gives the concrete realization of database applications.
Key words: JDBC; database; database Connection Pool
1 引言
隨著網絡的發展,各種網站越來越多。而對于基于數據庫的Web系統來說,數據庫連接是增加系統開銷的主要原因之一,它的好壞直接影響到數據庫服務器的性能。傳統的數據庫連接是在主程序(如Servlet、Beans)中建立數據庫連接,然后進行SQL操作取出數據,最后結束時斷開數據庫連接。這就使得每次用戶的請求都需要建立一次數據庫連接,這就大大地增加系統開銷,并且降低數據庫服務器的性能。此外,采用傳統的連接方式,需要你去管理每一個連接,并確保他們能被正確關閉,如果出現程序異常而導致某些連接未能正常關閉,這將導致數據庫系統中的內存泄露,最終我們將不得不重啟數據庫。由上面的分析可以看出,問題的根源就在于對數據庫連接資源的低效管理。這就需要引入一種高效率的資源管理機制來解決該問題。
2 基于JDBC的傳統數據庫訪問機制
JDBC(Java Database Connectivity)是Java與數據庫的接口規范,它由一組用Java編程語言編寫的類和接口組成。它可分為兩類:面向開發人員的JDBC API和面向數據庫開發商的底層的JDBC driver API。而JDBC驅動程序由實施了這些接口的類組成。
下面先介紹Java語言通過JDBC技術訪問數據庫的過程。
①裝載JDBC驅動程序;
②獲得JDBC數據庫連接;
③創建Statement對象;
④執行SQL語句;
⑤處理結果;
⑥關閉數據庫連接。
分析以上內容,我們可以這樣理解:用戶每次的訪問都需要向數據庫服務器提出連接請求,而且每次使用后都要關閉。這使得數據庫連接效率極低。
下面將介紹一種高效率的資源管理機制—數據庫連接池。
3 數據庫連接池的工作原理
數據庫連接池的實現原理就是為數據庫連接建立一個“緩沖池”,預先在這個\"緩沖池\"中放入一定數量的數據庫連接,當應用程序需要時,就從“緩沖池”中取出一個連接,使用完后再放回“緩沖池”中。同時我們通過設置連接池最大連接數來防止系統無窮無盡地與數據庫連接。更為重要的是我們可以通過連接池的管理機制監視數據庫的連接的數量﹑使用情況,為系統開發﹑測試及性能調整提供依據。連接池主要包括三個方面:連接池的建立、管理和關閉。下面將主要討論它們及連接池的配置。
3.1 建立連接池
在系統初始化時根據連接配置文件Connections.properties建立連接池并創建一定數量的數據庫連接,這些數據庫連接的數量是由最小數據庫連接數來設定的。無論這些數據庫連接是否被使用,連接池都將一直保證至少擁有這么多的連接數量。以后所使用的連接都是從該連接池中獲取的。Java中提供了很多容器類可以方便的構建連接池,如:Vector、Stack、Servlet、Bean等。
3.2 連接池的管理
連接池管理是連接池機制的核心,對系統的性能有很大的影響。當連接池建立后,如何對連接池中的連接進行管理,解決好連接池內連接的分配和釋放,對系統的性能有很大的影響。連接的合理分配、釋放可提高連接的復用,降低了系統建立新連接的開銷,同時也加速了用戶的訪問速度。
連接池管理是采用兩級連接池一空閑池和使用池。空閑池中存放目前還沒有分配出去的連接,一旦一個連接被分配出去,它就會被放入到使用池中,并且增加引用記數。這里的引用記數(ReferenceCounting)是一種對于復用資源廣泛使用的設計模式。我們把該方法運用到對于連接的分配釋放上。每一個數據庫連接,保留一個引用記數,用來記錄該連接的使用者的個數。
具體的實現方法是:
當用戶請求數據庫連接時,首先檢查空閑池內有沒有空閑的連接(是指未分配的連接),如果有就把建立時間最長的連接分配給他,在此先判斷該連接是否有效即引用記數是否小于可用次數(ConnectionUseCount),如果小于就分配給用戶,否則就把該連接從空閑池中刪掉,重新檢查空閑池是否有連接;
如果沒有連接則檢查當前所開連接池是否達到其最大的連接數,如果沒有達到,就按設定的WaitConnectionTime(最大等待時間)進行等待一段時間;如果達到就,如果達到則如果沒達到就重新創建一個連接給請求的用戶。如果等待WaitConnectionTime后仍沒有空閑連接,則返回空值(NULL)給用戶。如果在等待的時間里,有連接被釋放出來就可以把這個連接分配給等待的用戶。
如果存在則取出可用連接對該連接把連接分配給客戶并作相應處理(即標記該連接為正在使用,引用記數加1);如果沒有空閑連接,則查看當前所開的連接數是不是已經達到MaxConnections(最大連接數)。
釋放數據庫連接時要做三件事:首先有一個等待,詢問本次連接中是否還有同一事務的其他SQL語句,如有則接著本次連接繼續操作;如無則計算該連接對象的引用次數并判斷是否超過了該連接的可用次數,如果超過就從連接池中刪除該連接,以防止同一個連接使用次數過多,導致連接不穩定,否則就將該連接放入空閑池并設置為空閑狀態,可供再次復用;最后檢查當前連接池內空閑連接數是否小于MinConnections(最少連接數),若小于就新建若干個空閑連接,使連接池動態地保持一定量的空閑連接;否則關閉該連接。我們可以看出正是這套策略保證了數據庫連接的有效復用,避免頻繁地建立、釋放連接所帶來的系統資源開銷。
3.3 連接池的關閉
當應用程序退出時,應關閉連接池,此時應把在連接池建立時向數據庫申請的連接對象統一歸還給數據庫(即關閉所有數據庫連接),這與連接池的建立正好是一個相反過程。
3.4 連接池的配置
數據庫連接池到底要放置多少個連接,這是個配置策略。這里的配置策略是:根據具體的應用需求,給出一個初始的連接池連接數目以及一個連接池可以承受的最大連接數目。本方案就是按照這個策略實現的。
4 數據庫連接池的具體實現
從連接池的基本原理可以發現,一個連接池在創建和管理的過程中是由一組基本屬性和接口來控制的。它們控制著連接池和每個連接對象的有效狀態值,同時也影響著連接池的性能。基本方法如下:
Public class DBConnectionsPool {
MinConnections:初始化時連接池建立的最少連接數,即連接池動態維持的空閑連接數;
MaxConnections:連接池中最大連接數;
ConnectionUseCount:一個連接的最大使用次數;
WaitConnectionTime :等待分配空閑連接的最大等待時間;
Connections:當前的連接數即動態維持的連接數;
WaitReleaseTime:連接釋放前的等待時間;
Public Synehronized void freeConnection(Connection con)//將連接返回給連接池
Public Synehronized Connection getConnection()//從連接池獲得可用連接
Public Synehronized Connection getConnection(long maxWaitTime)//從連接池獲取可用連接,并指定客戶程序能夠等待的最長時間。
Private Connection newConnection()//創建新連接
Public synehronized void release()//關閉所有連接。
}
Public class DBConnectionManager{
GetInstance()方法//訪問連接池的唯一實例
Private DBConnectionManager()//建構函數私有以防止其它對象創建本類實例
GetResourceASStream()方法//用于定位并打開外部文件
Connections.properties//屬性文件,它包含定義連接池的鍵一值對。
LoodDrivers()方法//實現裝載和注冊所有在drivers屬性中指定的JDBC驅動程序
CreatePools()//創建連接池對象。
Hashtable類//實現連接池名字到連接池對象之間的映射。
public void freeConnection(String name, Connection con)// 釋放一個連接,//name是一個連接池對象的名字
public Connection getConnection(String name)//從名字為name的連接池對象//中得到一個連接
public Connection getConnection(String name, long time)//從名字為name的連接池對象中取得一個連接,time是等待時間
}
對于大型的企業級應用,常常需要同時連接不同的數據庫(如連接Oracle和Sybase)。我們先建立配置文件并且存放多個數據庫的基本信息,然后通過讀取文件的信息來分別創建多個連接池類的實例,每一個實例都是一個特定數據庫的連接池。連接池管理類實例為每個連接池實例取一個名字,通過不同的名字來管理不同的連接池。當所連接的數據庫服務器有改動時,通過重新設置配置文件,可以連接各種數據庫服務器。連接池初始化之前,首先讀入配置文件,下面介紹一個關于SQL 2000的例子:
jdbc.drivers= com.microsoft.jdbc.sqlserver.SQLServerDriver
jdbc.url= jdbc:microsoft:sqlserver://localhost:3306/corejava
jdbc.username=dww
jdbc.password=123456
5 結束語
在使用JDBC進行與數據庫連接有關的應用開發中,對于眾多用戶訪問的Web應用,采用數據庫連接池技術的系統在效率和穩定性上比采用傳統的其他方式的系統要好很多。該文在原有的JDBC上提出一個合理、高效的數據庫連接池的設計與實現,避免了對于連接的任意、無規則的使用,使得數據庫連接可以得到高效安全的復用,提高系統的效率。
參考文獻:
[1] 梁立新.項目實踐精解:Java Web應用開發[M].北京:電子工業出版社.2007.
[2] 王秀義.基于JDBC的數據庫連接池及實現[J].計算機系統應用,2004,(4):36-39.
[3] 成培,李峰,王暢.連接池數據庫訪問技術深入研究[J].計算機工程與設計,2007,(28):509-511.
[4] 商杰,朱站立.數據庫連接技術研究與應用[J].現代電子技術,2007.(5):95-97.
[5] 王士信,喻國平.基于JSP的數據庫連接池及其應用[J].微計算機信息,2008,(24):137-138,152.