戴長秀
摘 要: 應用程序用JDBC訪問數(shù)據(jù)庫需要頻繁的建立連接和關閉連接,由于數(shù)據(jù)庫連接數(shù)的限制,當用戶數(shù)、連接數(shù)達到一定程度時,用JDBC訪問數(shù)據(jù)庫的速度將會明顯下降,甚至需要重啟數(shù)據(jù)庫系統(tǒng),這極大地降低了數(shù)據(jù)庫應用系統(tǒng)的性能。連接池較好地解決了上述問題,避免了連接數(shù)增加引起的數(shù)據(jù)庫性能瓶頸問題。文章介紹了連接池的靜態(tài)、動態(tài)創(chuàng)建,引用記數(shù)法分配連接等實現(xiàn)原理,對連接池的配置進行了論述。實踐表明,連接池可以很好地提高數(shù)據(jù)庫應用系統(tǒng)的整體性能。
關鍵詞: 連接池; 靜態(tài); 動態(tài); 引用記數(shù)
中圖分類號:TP311.52 文獻標志碼:A 文章編號:1006-8228(2017)11-20-03
Research and application of connection pool to access database
Dai Changxiu
(Department of Information Science and Technology, Guangdong University of Foreign Studies South China Business College, Guangdong, Guangzhou 510545, China)
Abstract: The applications using JDBC to access database need to establish and close the connections frequently, because of the limitation of database connection, when the number of users, the number of connections increase to a certain extent, the speed of accessing database with JDBC will be decreased obviously, even need to restart the database system, which greatly reduces the performance of database application system. The connection pool solves the above problem well and avoids the bottleneck of database performance caused by the increase of the connection number. This paper introduces the principle of the static and dynamic creation of connection pool, and the principle of distributing connections with reference counting method, and discusses the configuration of connection pool. The practice shows that the connection pool can improve the overall performance of database application system.
Key words: connection pool; static; dynamic; reference counting
0 引言
Web應用程序最常用的數(shù)據(jù)管理方式就是使用關系數(shù)據(jù)庫,往往都是用數(shù)據(jù)庫存儲的信息動態(tài)生成Web頁面[1]。在基于JDBC訪問數(shù)據(jù)庫方式中,每個用戶在請求訪問數(shù)據(jù)庫前都必須先建立連接,建立連接將會消耗系統(tǒng)一定資源,延長訪問數(shù)據(jù)庫的時間。當然,如果是單個用戶請求訪問,這個延時是比較小的,用戶體會不到。但是,如果是批量用戶、批量請求,這個延時將會急速劇增。同時還可能出現(xiàn)由于連接的不及時關閉而導致數(shù)據(jù)庫內(nèi)存泄露,數(shù)據(jù)庫系統(tǒng)重啟,從而系統(tǒng)無法響應用戶請求問題。眾所周知,每種數(shù)據(jù)庫在同一時刻都有允許的最大連接數(shù),隨著流量、用戶的增加,數(shù)據(jù)庫連接數(shù)達到一定數(shù)量時,數(shù)據(jù)庫的性能就會急劇下降,甚至崩潰。
數(shù)據(jù)庫連接池技術很好的解決了上述問題,連接池通過預先建立一定數(shù)量的數(shù)據(jù)庫連接為應用程序提供連接。當應用程序訪問數(shù)據(jù)庫時,應用程序就可以從連接池中取出一個事先建立好的數(shù)據(jù)庫連接來訪問數(shù)據(jù)庫,從而免去每次訪問數(shù)據(jù)庫時建立數(shù)據(jù)庫連接的開銷,同時也可以減少數(shù)據(jù)庫連接和斷開時造成的程序錯誤[2]。數(shù)據(jù)庫連接池技術不僅節(jié)省了數(shù)據(jù)庫建立連接的時間,而且通過池化管理機制,可以有效地使用和調(diào)度連接池中的連接,從而很好地解決數(shù)據(jù)庫連接數(shù)量限制問題。
1 連接池的實現(xiàn)原理
服務器在啟動時創(chuàng)建連接池,同時建立一定數(shù)量的數(shù)據(jù)庫連接。當用戶請求數(shù)據(jù)庫連接時,服務器為其分配連接。當用戶請求數(shù)量超出了已建立好的數(shù)據(jù)庫連接數(shù)目時,服務器為其創(chuàng)建新的數(shù)據(jù)庫連接或者復用已分配出去的數(shù)據(jù)庫連接或者處于等待狀態(tài)。通常情況下,使用連接池來訪問數(shù)據(jù)庫包含以下兩個步驟:
⑴ 創(chuàng)建連接池;
⑵ 分配、釋放連接。
1.1 創(chuàng)建連接池
創(chuàng)建連接池的方法有靜態(tài)和動態(tài)之分,所謂靜態(tài)是指,池中的連接是系統(tǒng)初始化時已創(chuàng)建好的,并且不能隨意的關閉,這樣就可以避免因連接隨意建立、關閉而造成的系統(tǒng)開銷[3]。在系統(tǒng)初始化時,根據(jù)配置文件中的參數(shù)創(chuàng)建數(shù)據(jù)庫連接并放置在連接池中,以后應用程序使用數(shù)據(jù)庫連接時就從該連接池中獲取,連接池相對于應用程序來說是惟一的,數(shù)據(jù)庫連接數(shù)也是固定的。所謂的動態(tài)是指可以動態(tài)的加載、修改、刪除連接池,可以為不同類型的數(shù)據(jù)庫同時創(chuàng)建連接池,可以靈活地配置連接池參數(shù)。動態(tài)方法解決了靜態(tài)方法中靜態(tài)加載連接池的局限性,解決了連接池不能適時增刪改,配置參數(shù)不能根據(jù)應用變化靈活調(diào)整的問題[4]。endprint
1.2 分配、釋放連接
創(chuàng)建好連接池后,需要提供一套有效的分配連接機制以保證數(shù)據(jù)庫連接的有效使用。當應用程序請求一個數(shù)據(jù)庫連接時,連接池通常以連接建立時間長短為分配原則為該請求分配一個建立時間最長的空閑的連接,此處的空閑是指沒有被分配出去的連接,如果連接池中沒有空閑連接,則檢查當前連接池中連接數(shù)是否達到設定的最大值,如果沒有達到就新建一個連接,如果已達到連接池中所允許的最大連接數(shù),則該請求等待一定時間,如果在設定的等待時間內(nèi)還沒有數(shù)據(jù)庫連接被釋放出來,則返回空值。
連接池中最小連接數(shù)的檢測有動態(tài)和靜態(tài)兩種方法,動態(tài)方法是指每隔一定時間系統(tǒng)自行檢測連接池中連接數(shù),如果發(fā)現(xiàn)數(shù)據(jù)庫連接數(shù)低于最小連接數(shù)的設定值,則補充相應數(shù)量的新連接,從而保證連接池的正常運轉(zhuǎn)。靜態(tài)方法是指發(fā)現(xiàn)空閑連接不夠使用時系統(tǒng)再去檢測數(shù)據(jù)庫連接數(shù)并與設定的最小連接數(shù)進行對比。
在分配數(shù)據(jù)連接時,除了使用空閑連接外,也可以復用正在使用的數(shù)據(jù)庫連接,復用正在使用的數(shù)據(jù)庫連接通常使用Reference Counting(引用記數(shù))方法。該方法會為每一個數(shù)據(jù)庫連接保留一個引用記數(shù)值,用來記錄該連接的使用者的個數(shù)。具體操作是采用兩級連接池,一個空閑池用于存放目前還沒分配出去使用的的連接,另一個使用池存放目前已被分配出去使用的連接,并且為每個數(shù)據(jù)庫連接設置相應的引用記數(shù)值。當所有的數(shù)據(jù)庫連接都已分配出去使用時則選擇引用記數(shù)值較小的數(shù)據(jù)庫連接進行復用,這樣可以避免隨意選擇數(shù)據(jù)庫連接進行復用,達到數(shù)據(jù)庫連接可管理的目的[5]。
2 靜態(tài)連接池的配置
連接池應建立多少數(shù)據(jù)庫連接數(shù),才能使系統(tǒng)的性能處于最佳狀態(tài),發(fā)揮最好的性能,這個值的設置需要參考系統(tǒng)的用戶數(shù),需要開發(fā)人員經(jīng)過反復測試,最后才能找到最佳的設置值。
2.1 配置參數(shù)介紹
連接池的配置方法有很多,可以在Tomcat下配置,也可以使用JSP的框架如Struts、Spring和Hibernate,還可以使用開源提供的連接池組件。在此,只針對Tomcat下連接池的配置進行介紹。JDBC2.0提供了javax.sql.DataSourse接口負責數(shù)據(jù)庫的建立,在應用時無需編寫數(shù)據(jù)庫連接代碼,就可以直接從數(shù)據(jù)源中獲得數(shù)據(jù)庫連接。在DataSourse接口中預先建立好數(shù)據(jù)庫連接并放置在連接池中,當用戶請求訪問數(shù)據(jù)庫時,應用程序直接從連接池中取出空閑的連接,訪問結束后,再將連接返回給連接池。Tomcat服務器正是通過DataSourse接口獲取數(shù)據(jù)庫連接,雖然不能為DataSourse接口創(chuàng)建實例,但是可以通過Java命名和目錄接口(JNDI)來獲取DataSourse接口的引用,在配置數(shù)據(jù)源時需要使用的有關參數(shù)及含義如下。
Name:設置數(shù)據(jù)源的JNDI名。
Type:設置數(shù)據(jù)源的類型。
Auth:設置數(shù)據(jù)源的管理者,有兩個可選值Container和Application,Container表示由容器來創(chuàng)建和管理數(shù)據(jù)源,Application表示由Web應用來創(chuàng)建和管理數(shù)據(jù)源。
driverClassName:設置連接數(shù)據(jù)庫的JDBC驅(qū)動程序。
url:設置連接數(shù)據(jù)庫的路徑。
username:設置連接數(shù)據(jù)庫的用戶名。
password:設置連接數(shù)據(jù)庫的密碼。
maxActive:設置連接池中處于活動狀態(tài)的數(shù)據(jù)庫連接的最大數(shù)目,0表示不受限制。
maxIdle:設置連接池中處于空閑狀態(tài)的數(shù)據(jù)庫連接的最大數(shù)目,0表示不受限制。
maxWait:設置當連接池中沒有處于空閑狀態(tài)的連接時,請求數(shù)據(jù)庫連接的請求的最長等待時間(單位為ms),如果超出該時間將拋出異常,-1表示無限期等待。
2.2 數(shù)據(jù)源的配置
以SQL Server 2008為例,介紹在Tomcat 8.0下數(shù)據(jù)庫連接池的配置。
⑴ 復制數(shù)據(jù)庫驅(qū)動包。將SQL Server數(shù)據(jù)庫的JDBC驅(qū)動包sqljdbc.jar或者sqljdbc4.jar復制到Tomcat安裝路徑下的lib文件夾中。
⑵ 配置數(shù)據(jù)源。配置數(shù)據(jù)源時,可以將其配置到Tomcat安裝目錄下的conf\server.xml文件中,也可以將其配置到Web工程目錄下的META-INF\context.xml文件中,建議采用后者,因為這樣配置的數(shù)據(jù)源更有針對性,配置數(shù)據(jù)源的代碼如下:
auth="Container" type="javax.sql.DataSource" username="sa" password="123456" driverClassName="com.microsoft.sqlserver.jdbc .SQLServerDriver" url="="jdbc:sqlserver://127.0.0.1:1433; DatabaseName=db_database" maxActive="6" maxIdle="2"/>
3 連接池訪問數(shù)據(jù)庫的設計實現(xiàn)
創(chuàng)建名為JDBConnection.java類文件,在其構造方法中獲取DataSourse接口的引用。編寫DBTableDisplay.jsp文件,顯示數(shù)據(jù)庫表中信息。
JDBConnection類文件核心代碼如下:
……endprint
public class JDBConnection {
……
private Context ctx=null;
private Connection conn=null;
private DataSourse ds;
……
public JDBConnection() {
//類的構造方法,為Connection對象賦值
try {
ctx=new InitialContext();
ds=(DataSource)ctx.lookup("java:comp/env/jdbc/my_db"); //獲取連接池DataSource的引用
conn=ds.getConnection(); //得到連接
} catch(Exception e){……}
……
}
public Connection getConnection() {
//獲取Connection連接對象
return conn;
}
public ResultSet getResultSet(String sql) {
//獲取ResultSet記錄集對象
ResultSet rs;
try {
Statement stmt=conn.createStatement();
rs=stmt.executeQuery(sql);
} catch(Exception e){……}
……
return rs
}
……
}
在DBTableDisplay.jsp文件中創(chuàng)建JDBConnection實例,顯示數(shù)據(jù)庫表中的數(shù)據(jù)的核心代碼如下:
……
public JDBConnection DBConnection=null;
public ResultSet rs=null;
public String sql=null;
……
DBConnection=new JDBConnection();
rs=DBConnection.getResultSet (sql);
while(rs.next() {
//對數(shù)據(jù)庫表中的數(shù)據(jù)進行輸出顯示
}
……
4 結束語
盡管創(chuàng)建一個新的數(shù)據(jù)庫連接所耗費的時間主要取決于網(wǎng)絡的速度,以及應用程序與數(shù)據(jù)庫存服務器的網(wǎng)絡距離,然而這是一個比較耗時的過程。目前數(shù)據(jù)庫連接池技術已經(jīng)成為提高Java訪問數(shù)據(jù)庫效率的首選方案之一。本文針對傳統(tǒng)訪問數(shù)據(jù)庫方式的不足,分析了數(shù)據(jù)庫連接池技術的實現(xiàn)原理,并對連接池技術加以實現(xiàn)至應用。采用數(shù)據(jù)庫連接池后,數(shù)據(jù)庫請求可以直接通過連接池獲得滿足,不需要為該請求建立連接以及認證,從而為數(shù)據(jù)庫的訪問贏得了時間。盡管連接池中可能存在多個未被使用的數(shù)據(jù)庫連接,這在一定程度上會浪費系統(tǒng)資源,但是,開發(fā)人員通過反復試驗及測試,可以找到最佳的參數(shù)值從而將資源浪費減至最低。總之,使用連接池技術可以克服傳統(tǒng)訪問方式的不足,明顯地提高數(shù)據(jù)庫應用系統(tǒng)的整體性能。
參考文獻(References):
[1] 張玉林.用連接池提高Servlet訪問數(shù)據(jù)庫的效率[J].軟件技
術,2006.20:72-75
[2] 徐全生,齊祥玲.數(shù)據(jù)庫連接池在考試系統(tǒng)中的應用[J].沈陽
工業(yè)大學學報,2007.5:582-584
[3] 劉繼華.一種基于JDBC的數(shù)據(jù)庫連接池的設計與實現(xiàn)[J].計
算機工程與應用,2003.7:183-185
[4] 汪蔚,基于Java的數(shù)據(jù)庫連接池設計與優(yōu)化[J].交通科技與
經(jīng)濟,2009.4:108-109
[5] 劉菲、游達章,基于Java的數(shù)據(jù)庫連接池的設計與優(yōu)化[J].微
型電腦應用,2008.24:7-9endprint