池化数据库连接池 取出连接伪代码
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();
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。