一、簡介
動態Web站點往往用數據庫存儲的信息生成Web頁面,每一個頁面請求導致一次數據庫訪問。連接數據庫不僅要開銷一定的通信和內存資源,還必須完成用戶驗證、安全上下文配置這類任務,因為往往成為最為耗時的操作。
如果某個基於數據庫的應用系統只需建立一次初始連接或者使用很少的打開、關閉數據庫連接操作就可以完成工作,那么,系統的性能會得到顯著的改善。實現這種思路的方法是:使多個請求能夠共享同一個連接。連接池很好地滿足了這樣的要求,由連接池來管理數據連接的建立和注銷,初始化時建立多條連接,以供客戶使用。
用JSP開發Web應用系統,多數是基於數據庫的程序,建立數據庫連接的操作將是消耗系統資源最大的操作之一,如何減少這種開銷,是開發人員應該首要關注的問題。
如何開發基於數據庫的Web系統的傳統模式:
1、在JavaBeans或者Servlet中建立數據庫連接。
2、在頁面(JSP等)中調用JavaBeans獲取連接,執行Sql操作並返回結果集。
3、斷開數據庫連接。
連接池技術:
由連接池來管理數據庫連接的建立和注銷。連接池初始化時建立多條連接,供給不同的請求使用,多個請求可以共享同一連接,這樣做,就可以減少打開、關閉數據庫連接的操作,從而改善了系統的性能。
二、連接池原理介紹
顧名思義,連接池最基本的思想就是預先建立一些連接放置於內存對象中以備使用。
一個連接池“擁有”一定數量的連接,當客戶程序發出數據庫連接請求時,連接池會從“池”中取出一個空閑的連接給客戶程序,並將該連接狀態設置成已占用;當客戶程序使用完畢后,不會真正關閉這個連接,只是將其放回“池”中,同時將連接狀態設置成空閑。如果“池”中沒有空閑的連接,連接池可以根據某種策略自動地建立一個或多個連接,供后面的程序使用。
可見,連接的建立、斷開以及一個池可以擁有的最大連接數都由連接池自身管理,客戶程序可以不再關系這類事情,這樣就實現了連接的共享,提供了 每個連接的利用效率。
三、設計思路
使用連接池的目的是想通過其自身的管理機制來管理數據庫連接的狀態和使用情況,包括管理連接池內連接的最大數、最小數、穩定數、連接時間、可用連接等等。因此,一個連接池管理類應該具有以下屬性:
poolMaxSize: 最大連接數
poolSteadySize: 穩定大小
poolInitSize: 初始化大小
validPooledConnList: 容納可用的緩沖數據庫連接對象的容器——可用池
allPooledConnList: 所有的緩沖對象(可用的、不可用的)的容器——管理池
連接池的自由管理:靜態管理、動態管理
靜態管理:
靜態管理是在客戶程序發出請求時,連接池會檢查各個連接的狀態,並提供可用連接。運用連接池做一次連接的過程如下:
1. 初始化連接池,new 一定量的connection.
2. 客戶程序發出訪問數據庫的請求,連接池查找可用連接,如果找到,則直接返回一個連接。
3. 如果沒有空閑連接,則重新new 一個connection並且把它放到池里,然后返回這個connection.
4. 如果連接池滿了,程序是會停止new新的connection,客戶程序可以調用連接池的release方法釋放掉舊的連接。
動態管理:通過一個線程定時地對每個連接的狀態、連接的數量進行判斷而進行相應的操作。
public class ConnectionPool { public boolean initialize() { //連接池的初始化 return true; } public void destroy() { //連接池的銷毀 } public synchronized PoolConn getConnection() { //獲取一個連接 } public synchronized void close() { //關閉一個連接 } private synchronized void removeFormPool() { //把一個連接從連接池中移除 } public static synchronized void packPool() { //維護連接池的大小 } }
通過這幾個方法,已經可以完成連接池的基本管理。因為我們要保存每一個連接的狀態,所以還需要一個數據庫連接對象:
class ConnObject { private java.sql.Connection conn; public java.sql.Connection getConn() { } public void closeConn() { } }
這樣,在連接池中操作的連接對象是ConnObject,當其他程序訪問數據庫時需要的只是ConnObject的conn屬性,因為我們再加入一個類,封裝這個實際的數據庫連接對象,作為其他程序獲得和釋放數據庫連接的方法。
class ConnBean { public java.sql.Connection getConnection();//從連接池中取出一個有效的連接 public void releaseConnection();//釋放連接,此時並沒有關閉連接,只是將連接放回連接池中 protected void setConnection(java.sql.Connection conn); void destroyPool();//銷毀連接池 }