系統情境:系統依賴多個資料庫。其中一台資料庫伺服器運行ORACLE,同時還有數台機器上跑著ObjectServer記憶體資料庫。由於到部署時才能確定從機的數量,因此需要動態建立串連池
方案:Oracle資料庫用c3p0來管理串連池。另外寫一個連線管理員來動態建立記憶體資料庫連接池
代碼:經過簡化,只貼出關鍵代碼,去掉日誌、異常處理、null檢查等
// ObejctServer串連池,系統中域的數量與該類執行個體一一對應 public class DBConnectionPool{ private int checkedOut;// 已檢出的串連數 private Vector<Connection> freeConnections = new Vector<Connection>();// 空閑串連數 // 返還串連 public synchronized void freeConnection(Connection con, Object lock) { freeConnections.addElement(con); this.checkedOut--; lock.notifyAll(); } // 從串連池中擷取串連 public Connection getConnection(Object lock) { Connection con; while ((con = fetchConnection()) == null)// 迴圈調用fetchConnection()方法 { lock.wait(timeout);// 沒擷取到可用串連,則等待 // 如果逾時了,則return null } return con; }}
// ObjectServer連線管理員public class DBConnectionManager{ private Hashtable<String, DBConnectionPool> pools;// 串連池集合,每個OS域都有一個串連池 private static final byte[] lock = new byte[0];// 同步鎖 // 返還串連 public void freeConnection(String domainName, Connection conn) { synchronized (lock) { DBConnectionPool pool = (DBConnectionPool) pools.get(domainName);// 得到網域名稱對應的串連池 pool.freeConnection(conn, lock); } } // 獲得某從機上的可用串連 public Connection getConnection(String domainName) { synchronized (lock) { DBConnectionPool pool = (DBConnectionPool) pools.get(domainName); if (null != pool)// 串連池已存在,直接使用 { return pool.getConnection(lock); } else { registerNewConnectionPool(poolProvide);// 註冊新串連池 return getConnection(domainName);// 遞迴調用 } return null; } }}