三 代码解读
1. 连接池管理
先看如何获取到数据库连接, 以此为入口。 在 ProxoolDataSource 中:
public Connection getConnection() throws SQLException { ConnectionPool cp = null; try { if (!ConnectionPoolManager.getInstance().isPoolExists(alias)) { registerPool(); } cp = ConnectionPoolManager.getInstance().getConnectionPool(alias); return cp.getConnection(); } catch (ProxoolException e) { LOG.error("Problem gettingconnection", e); throw new SQLException(e.toString()); } }
根据 ProxoolDataSource 的 alias 属性先到连接池管理处查询是否已经有对应的连接池,如果没有,则注册相应的连接池, 如果有,则获取Connection 对象。 注册连接池的代码如下:
private synchronized void registerPool()throwsProxoolException { if (!ConnectionPoolManager.getInstance().isPoolExists(alias)) { ConnectionPoolDefinition cpd = newConnectionPoolDefinition(); cpd.setAlias(getAlias()); cpd.setDriver(getDriver()); // cpd.setXXX(getXXX()); // 设置各种属性 // We must setUser and setPassword*after* setDelegateProperties // otherwise the values will beoverwritten. Credit Bulent Erdemir. cpd.setUser(getUser()); cpd.setPassword(getPassword()); ProxoolFacade.registerConnectionPool(cpd); } }
ConnectionPoolManager有一个 connectionPoolMap 对象, 存储从 alias 到 ConnectionPool 的映射。 可见 alias 的重要性。 获取ProxoolDataSource对应的连接池的代码:
protected ConnectionPoolgetConnectionPool(String alias) throws ProxoolException { ConnectionPool cp = (ConnectionPool) connectionPoolMap.get(alias); if (cp == null) { throw newProxoolException(getKnownPools(alias)); } return cp; }
这是创建连接池的代码:
protected ConnectionPoolcreateConnectionPool(ConnectionPoolDefinition connectionPoolDefinition) throwsProxoolException { ConnectionPool connectionPool = newConnectionPool(connectionPoolDefinition); connectionPools.add(connectionPool); connectionPoolMap.put(connectionPoolDefinition.getAlias(),connectionPool); return connectionPool; }
事实上,ConnectionPoolManager 并没有做太多事情, 主要是管理ProxoolDataSource(alias)到相应ConnectionPool的映射关系。ProxoolFacade用于管理连接池的注册、移除及监听事件。注册连接池的主要工作:首先,在 ConnectionPoolManager中创建该连接池并添加映射, 接着启动该连接池的任务, 以及监听器的注册处理程序,最后处理 JDNI 及 JMX 相关。
protected synchronized static voidregisterConnectionPool(ConnectionPoolDefinition connectionPoolDefinition) throwsProxoolException { // check isPoolExists once morenow we are inside synchronized block. if (!ConnectionPoolManager.getInstance().isPoolExists(connectionPoolDefinition.getAlias())){ Properties jndiProperties = extractJndiProperties(connectionPoolDefinition); ConnectionPool connectionPool =ConnectionPoolManager.getInstance().createConnectionPool(connectionPoolDefinition); connectionPool.start(); compositeProxoolListener.onRegistration(connectionPoolDefinition,connectionPoolDefinition.getCompleteInfo()); if (isConfiguredForJMX(connectionPoolDefinition.getCompleteInfo())){ registerForJmx(connectionPoolDefinition.getAlias(),connectionPoolDefinition.getCompleteInfo()); } if (jndiProperties != null) { registerDataSource(connectionPoolDefinition.getAlias(),jndiProperties); } } else { LOG.debug("Ignoring duplicate attemptto register " + connectionPoolDefinition.getAlias()+ "pool"); } }
连接池启动任务代码如下:
/** Starts up house keeping andprototyper threads. */ protected void start() throwsProxoolException { connectionPoolUp = true; prototyper = new Prototyper(this); HouseKeeperController.register(this); } /** * Schedule a regular triggerSweep * @param connectionPool identifies the pool */ protected static void register(ConnectionPoolconnectionPool) { String alias =connectionPool.getDefinition().getAlias(); LOG.debug("Registering '" + alias + "' housekeeper"); HouseKeeper houseKeeper = newHouseKeeper(connectionPool); synchronized (LOCK) { houseKeepers.put(alias,houseKeeper); houseKeeperList.add(houseKeeper); if (houseKeeperThreads.size() == 0) { HouseKeeperThread hkt = newHouseKeeperThread("HouseKeeper"); LOG.debug("Starting a house keeperthread"); hkt.start(); houseKeeperThreads.add(hkt); } } }
后面再来看这个 houseKeeperThread 的任务内容。 这里暂时搁下。
2. 数据库连接管理
现在来看如何在连接池中获取数据库连接。 在 ConnectionPool 中,获取数据库连接的代码如下:
/** * Get a connection from
Proxool连接池解析(中)
最新推荐文章于 2021-02-28 23:41:19 发布
本文主要解析Proxool连接池的管理、数据库连接获取和扫描任务。通过ProxoolDataSource获取连接池,ConnectionPoolManager维护alias到ConnectionPool的映射。连接池启动时,HouseKeeperThread执行检查连接状态的任务,包括测试SQL、回收超时和活跃连接。PrototyperThread则负责在连接数低于最小值或空闲连接不足时创建新连接。整个过程涉及并发控制和状态管理,是理解Proxool核心功能的关键。
摘要由CSDN通过智能技术生成