池化数据库连接池 取出连接伪代码

    popConnection() {
        while(没有取到连接) {
            // 添加同步锁,防止多线程冲突
            if(连接池还有空余连接) {
                取出连接
            } else {
                if(连接池还有空余位置) {
                    创建新的连接
                } else {
                    if(借出去最久的连接已经超期不还) {
                        从连接池中删除超期不还的连接
                        新建一个连接
                    } else {
                        继续等待
                    }
                }
            }

            if(已经拿到连接) {
                if(连接可用) {
                    根据自动提交设置处理该连接上次使用时未提交的操作
                } else {
                    删除连接
                    if(所有连接都不可用) {
                        数据库无法连接,抛出异常
                    }
                }
            }
            释放同步锁;
        }
        if(取不到连接) {
            抛出异常
        }
        返回连接
    }

收回池化连接

    state.activeConnections.remove(conn)
    if(conn.isValid()){
        if(state.idleConnections.size() < poolMaximumIdleConnections) {
            if(conn.getConnectionType() == expectedConnectionType) {
                state.accumlateCheckoutTime += conn.getCheckoutTime();
                if(!conn.getRealConnection().getAutoCommit()) {
                    // 如果连接没有设置自动提交
                    // 将未完成的操作回滚
                    conn.getRealConnection().rollback();
                }

                // 重新整理连接
                PooledConnction newConn = new PooledConnection(conn.getRealConnection(), this);
                state.idleConnections.add(newConn);

                newConn.setCreateTimestamp(conn.getCreatedTimestamp());
                newConn.setLastUsedTimestamp(conn.getLastUsedTimestamp());
                // 设置连接为未校验,以便取出时重新校验
                conn.inValidate();
                condition.signal();
            } 
        } else {
            state.accumulatedCheckoutTiime += conn.getCheckoutTime();
            if(!conn.getRealConnection().getAutoCommit()) {
                conn.getRealConnection().rollback();
            }

            // 直接关闭连接
            conn.getRealConnection().close();
            conn.invalidate();
        }
    } else{
        // 当前连接不可用
        state.badConnectionCount++;
    }

收回池化连接伪代码

    pushConnection() {
        添加同步锁,防止多线程冲突
        将该连接从活跃连接列表中删除
        if(归还的连接可用) {
            if(连接池未满且该连接确实属于该连接池) {
                // 清理该连接;
                // 将该连接放入连接池
            } else {
                关闭连接

            }
        } else{
            记录该连接不可用
        }
        释放同步锁
    }

池化连接中如果jdbc相关配置变化了,运行中的connection如何进行感知


修改driver、url、username、password等配置,必须调用PooledDataSource的setDriver、setUrl、setUserName、setPassword等方法。其中每个方法中都会调用forceCloseAll()方法,强制关闭所有连接,如setDriver方法如下:

public void setDriver(String driver) {
    dataSource.setDriver(driver);
    forceCloseAll();
}

forceCloseAll() 流程

    public void forceCloseAll() {
        lock.lock();
        try {
            //重新计算和更新连接类型代码
            expectedConnectionTypeCode = assembleConnectionTypeCode(dataSource.getUrl(), dataSource.getUsername(), dataSource.getPassword());
            //依次关闭所有的活动连接
            for(int i = stateConnections.size(); i > 0; i--) {
                try {
                    PolledConnection conn = state.activeConnections.remove(i - 1);
                    conn.inValidate();

                    Connection realConn = conn.getRealConnection();
                    if(!realConn.getAutoCommit()) {
                        realConn.rollback();
                    }
                    realConn.close();
                }catch(Exception e) {
                    // NOP
                }
            }

            //依次关闭所有空闲连接
            for(int i = state.idleConnections.size(); i > 0;i--) {
                try{
                  PoolConnection conn =   state.ideleConnections.remove(i -1);
                  conn.inValidate();

                  Connection realConn = conn.getRealConnection();
                  if(!realConnection.getAutoCommit()) {
                    realConn.rollback();
                  }
                }catch(Exception e) {

                }
            }
        }catch(Exception e) {
            
        } finally {
            lock.unlock();
        }
    }

叮咚_打地鼠
0 声望0 粉丝

docker docker docker ing