Duird连接池连接管理

发布于:2025-03-07 ⋅ 阅读:(20) ⋅ 点赞:(0)

核心流程

时序图

流程说明

com.alibaba.druid.pool.DruidDataSource#getConnectionDirect 是 Druid 连接池中 获取连接的核心方法,负责从连接池中直接获取一个可用的数据库连接。它的核心逻辑包括 从空闲队列中获取连接创建新连接检查连接有效性 以及 处理连接获取失败的情况。以下是对其核心逻辑的详细说明。


一、getConnectionDirect 的核心作用

getConnectionDirect 的作用是从连接池中获取一个可用的数据库连接,具体包括以下功能:

  1. 从空闲队列中获取连接
    如果连接池中有空闲连接,则直接从空闲队列中获取。
  2. 创建新连接
    如果连接池中没有空闲连接且未达到最大连接数限制,则创建新的连接。
  3. 检查连接有效性
    在获取连接时,检查连接是否有效(如是否超时、是否被关闭等)。
  4. 处理连接获取失败的情况
    如果获取连接失败(如连接池已满、连接创建失败等),则抛出异常或阻塞等待。

二、getConnectionDirect 的核心流程

以下是 getConnectionDirect 方法的详细流程:

1. 检查连接池状态

  • 检查连接池是否已关闭。如果已关闭,则抛出 IllegalStateException 异常。

2. 从空闲队列中获取连接

  • connections(空闲连接队列)中获取一个空闲连接。
  • 如果获取到连接,则检查连接的有效性:
    • 如果连接有效,则返回该连接。
    • 如果连接无效,则销毁该连接并继续尝试获取下一个连接。

3. 创建新连接

  • 如果连接池中没有空闲连接且未达到最大连接数限制,则调用 createPhysicalConnection() 方法创建新的连接。
  • 将新连接包装为 DruidPooledConnection 并返回。

4. 处理连接获取失败的情况

  • 如果连接池已满,则根据配置决定是否阻塞等待:
    • 如果 maxWait 大于 0,则阻塞等待,直到有可用连接或超时。
    • 如果 maxWait 小于等于 0,则立即抛出 SQLException 异常。

5. 返回连接

  • 返回获取到的可用连接。

三、getConnectionDirect 的核心代码逻辑

以下是 getConnectionDirect 方法的简化代码逻辑:

private DruidPooledConnection getConnectionDirect(long maxWaitMillis) throws SQLException {
    // 1. 检查连接池状态
    if (closed) {
        throw new IllegalStateException("DataSource already closed");
    }

    // 2. 从空闲队列中获取连接
    DruidConnectionHolder holder = null;
    while (holder == null) {
        holder = connections.poll();
        if (holder != null) {
            // 检查连接有效性
            if (!holder.isValid()) {
                // 销毁无效连接
                destroyConnection(holder);
                holder = null;
            }
        } else {
            // 3. 创建新连接
            if (poolingCount < maxActive) {
                holder = createPhysicalConnection();
                break;
            } else {
                // 4. 处理连接获取失败的情况
                if (maxWaitMillis <= 0) {
                    throw new SQLException("Connection pool is full");
                }
                // 阻塞等待
                holder = connections.poll(maxWaitMillis, TimeUnit.MILLISECONDS);
            }
        }
    }

    // 5. 返回连接
    return new DruidPooledConnection(holder);
}

四、getConnectionDirect 的核心类和方法

1. connections

  • 空闲连接队列,用于存储可用的数据库连接。
  • 通常是 LinkedBlockingQueueArrayBlockingQueue

2. createPhysicalConnection()

  • 创建真实的数据库连接,并将其包装为 DruidConnectionHolder

3. destroyConnection()

  • 销毁无效的数据库连接,释放相关资源。

4. DruidConnectionHolder

  • 连接的持有者类,封装了真实的数据库连接及其元数据。

5. DruidPooledConnection

  • 代理连接类,包装了 DruidConnectionHolder,提供对连接的监控和管理功能。

五、getConnectionDirect 的核心设计思想

1. 连接池调度

  • 通过空闲队列管理连接,确保连接的获取和回收高效有序。

2. 连接有效性检查

  • 在获取连接时检查连接的有效性,避免返回无效连接。

3. 资源管理

  • 在连接无效或连接池已满时,及时销毁连接或阻塞等待,避免资源浪费。

4. 高并发支持

  • 通过线程安全的队列和锁机制,支持高并发场景下的连接获取和回收。

六、总结

com.alibaba.druid.pool.DruidDataSource#getConnectionDirect 是 Druid 连接池中获取连接的核心方法,其核心逻辑包括:

  1. 从空闲队列中获取连接。
  2. 创建新连接。
  3. 检查连接有效性。
  4. 处理连接获取失败的情况。

通过优化的调度算法和资源管理机制,getConnectionDirect 在高并发场景下表现出色,能够高效地管理数据库连接。如果需要更深入的源码分析或性能优化,可以参考 Druid 的官方文档和源码。