首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

資料庫連線池 Java 實作總結:動態代理、單例工廠與雙池管理架構

     編輯:Java 相關知識

設計目標

  • 消除頻繁建立連線開銷與瓶頸。
  • 保留標準 JDBC 使用習慣(直接呼叫 close() 歸還池中)。
  • 確保連線狀態正確維護(Statement/PreparedStatement 自動清理)。
  • 保護核心類別不被誤用(僅工廠可建立連線包裝器)。
  • 提供簡潔 API:ConnectionFactory.bind() → ds.getConnection() → conn.close()。

核心類別架構

  1. ConnectionParam:不可變配置物件(驅動、URL、帳密),實作 Serializable、equals/hashCode。
  2. FactoryParam:池參數(最小/最大連線數、管理策略:0靜態/1動態)。
  3. _Connection:InvocationHandler 實作,包裝真實連線,攔截關鍵方法:
// 攔截邏輯精簡版
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
    String name = m.getName();
    if ("close".equals(name)) {
        inUse = false; closeStatements(); return null; // 歸還池中
    }
    if ("createStatement".equals(name)) { stmtRef = (Statement) m.invoke(conn, args); return stmtRef; }
    if ("prepareStatement".equals(name)) { pstmtRef = (PreparedStatement) m.invoke(conn, args); return pstmtRef; }
    if (("commit".equals(name) || "rollback".equals(name)) && !supportsTx) return null;
    return m.invoke(conn, args);
}
void reallyClose() throws SQLException { conn.close(); } // 池關閉時呼叫
  1. ConnectionFactory:單例工廠(雙重檢查鎖定實作單例),管理命名池 Hashtable,提供 bind/lookup/rebind/unbind。建構子私有,靜態工廠方法初始化池參數、預建最小連線、啟動動態管理執行緒。
  2. DataSourceImpl:實作 javax.sql.DataSource,內部雙集合:FreeConnectionPool (LinkedHashSet)、BusyConnectionPool。核心邏輯:
public synchronized Connection getFreeConnection() throws SQLException {
    // 1. 從閒置池取出
    // 2. 閒置池空則檢查是否可新建(未達上限)
    // 3. 不可新建則從忙碌池尋找已歸還連線
    // 4. 仍無則拋出異常
    wrapper.inUse = true;
    moveToBusy(wrapper);
    return wrapper.getProxy();
}
public void schedule() { /* 動態管理:回收超時、補充閒置至最小值 */ }
public void close() { /* 關閉所有真實連線 */ }
  1. FactoryManageThread:動態管理策略啟用時的背景執行緒,每秒呼叫 schedule(),工廠關閉時自動結束。

使用範例

ConnectionParam param = new ConnectionParam(driver, url, user, pass);
ConnectionFactory cf = new ConnectionFactory(param, new FactoryParam(5, 2, 1)); // 動態管理
DataSource ds = ConnectionFactory.lookup("pool");
for (int i=0; i<10; i++) {
    Connection c = ds.getConnection();
    try { c.createStatement().executeQuery("SELECT 1"); }
    finally { c.close(); } // 透明歸還
}
cf.unbind("pool"); // 關閉池

效能驗證

測試 10 次查詢:連線池 ~200ms vs 無池 ~1200ms(含驅動載入與連線建立),顯著降低延遲。

原始碼結構

六個類別:_Connection、ConnectionFactory、ConnectionParam、FactoryManageThread、FactoryParam、testmypool,皆置於 scut.ailab.connectionpool 套件,完整原始碼已附於文末。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved