一般情況下,在使用開發基於資料庫的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();
//銷毀串連池
}
最後我們的整個系統總的架構如下: