天天看點

資料庫連接配接池技術淺析(轉)

資料庫連接配接池技術淺析(轉)

一般情況下,在使用開發基于資料庫的WEB程式時,傳統的模式基本是按以下步驟:

1. 在主程式(如Servlet、Beans)中建立資料庫 連接配接。

2. 進行SQL操作,取出資料。

3. 斷開資料庫連接配接。

使用這種模式開發,存在很多問題。首先,我們要為每一次WEB請求(例如察看某一篇文章的内容)建立一次資料庫連接配接,對于一次或幾次操作來講,或許你覺 察不到系統的開銷,但是,對于WEB程式來講,即使在某一較短的時間段内,其操作請求數也遠遠不是一兩次,而是數十上百次(想想全世界的網友都有可能在您 的網頁上查找資料),在這種情況下,系統開銷是相當大的。事實上,在一個基于資料庫的WEB系統中,建立 資料庫 連接配接的操作将是系統中代價最大的操作之一。很多時候,可能您的網站速度瓶頸就在于此。

其次,使用傳統的模式,你必須去管理每一個連接配接,確定他們能被正确關閉,如果出現程式異常而導緻某些連接配接未能關閉,将導緻資料庫系統中的記憶體洩露,最終我們将不得不重新開機 資料庫。

針對以上問題,我們首先想到可以采用一個全局的Connection對象,建立後就不關閉,以後程式一直使用它,這樣就不存在每次建立、關閉連接配接的問題 了。但是,同一個連接配接使用次數過多,将會導緻連接配接的不穩定,進而會導緻WEB SERVER的頻頻重新開機。故而,這種方法也不可取。實際上,我們可以使用連 接池技術來解決上述問題。首先,介紹一下連接配接池技術的基本原理。顧名思義,連接配接池最基本的思想就是預先建立一些連接配接放置于記憶體對象中以備使用:

資料庫連接配接池技術淺析(轉)

如 圖所示,當程式中需要建立資料庫連接配接時,隻須從記憶體中取一個來用而不用建立。同樣,使用完畢後,隻需放回記憶體即可。而連接配接的建立、斷開都有連接配接池自身來管 理。同時,我們還可以通過設定連接配接池的參數來控制連接配接池中的連接配接數、每個連接配接的最大使用次數等等。通過使用連接配接池,将大大提高程式效率,同時,我們可以通 過其自身的管理機制來監視資料庫連接配接的數量、使用情況等。下面我們以一個名為ConnectionPool的連接配接池為例來看看連接配接池的實作。先看看ConnectionPool的基本屬性:

m_ConnectionPoolSize:連接配接池中連接配接數量下限

m_ConnectionPoolMax:連接配接池中連接配接數量上限

m_ConnectionUseCount:一個連接配接的最大使用次數

m_ConnectionTimeout:一個連接配接的最長空閑時間

m_MaxConnections = -1:同一時間的最大連接配接數

m_timer:定時器

這些屬性定義了連接配接池與其中的每個連接配接的有效狀态值。連接配接池的自我管理,實際上就是通過定時的對每個連接配接的狀态、連接配接的數量進行判斷而進行相應操作。其管理流程如下:

資料庫連接配接池技術淺析(轉)

通過上圖,我們可以定義出ConnectionPool要完成管理所需要的基本接口:

public class ConnectionPool implements TimerListener{

public boolean initialize() //連接配接池初始化

public void destroy() //連接配接池的銷毀

public synchronized java.sql.Connection getConnection() //取一個連接配接

public synchronized void close() //關閉一個連接配接

private synchronized void removeFromPool() //把一個連接配接從連接配接池中删除

private synchronized void fillPool() //維護連接配接池大小

public synchronized void TimerEvent() //定時器事件處理函數

}

通過這幾個接口,已經可以完成連接配接池的基本管理。在TimeEvent()函數中完成連接配接池的狀态檢驗工作,fillPool()時連接配接池至少保持最小連接配接數。因為我們要儲存每一個連接配接的狀态,是以還需要一個資料庫連接配接對象:

class ConnectionObject{

public java.sql.Connection con; public boolean inUse; //是否被使用标志

public long lastAccess; //最近一次開始使用時間

public int useCount; //被使用次數

}

加 入了ConnectionObject對象後,在ConnectionPool中操作的應該隻是ConnectionObject,而其他程序需要的隻是 ConnectionObject的con屬性,是以我們再加入一個類,作為其他程序獲得與傳回連接配接的接口: CLASS Conn{

GetConnection(); //從連接配接池中取出一個有效連接配接

CloseConnection(); //傳回連接配接,此時并沒有關閉連接配接,隻是放回了連接配接池

DestroyPool(); //銷毀連接配接池

}