聊聊Mybatis的数据源之PooledDataSource获取连接

举报
周杰伦本人 发表于 2022/08/29 21:51:41 2022/08/29
【摘要】 聊聊Mybatis的数据源之PooledDataSource获取连接 获取数据库连接 popConnection()方法 检测连接是否可用 总结 聊聊Mybatis的数据源之PooledDataSource获取连接这篇文章我们对数据源池的获取连接的过程进行分析讲解一下 获取数据库连接获取数据库的连接调用getConnection()方法: @Override public Co...

聊聊Mybatis的数据源之PooledDataSource获取连接

这篇文章我们对数据源池的获取连接的过程进行分析讲解一下

获取数据库连接

获取数据库的连接调用getConnection()方法:

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return popConnection(username, password).getProxyConnection();
    }

popConnection()方法

然后分析一下popConnection()方法:

代码虽然比较长,占篇幅,我在这里就不贴代码了,但是方法的逻辑还是比较理解的:

先从空闲连接集合中获取连接信息,如果空闲集合中没有并活跃的连接数没有达到上限的时候就可以创建新的数据库连接,如果达到上限了就判断是否有超时的连接,如果有的话就利用这个超时连接创建新的连接并把超级连接设置为无效,如果超时连接也没有,这时候就调用wait方法进行阻塞

检测连接是否可用

PooledConnection的isValid()方法用来检测数据库连接是否可用

public boolean isValid() {
        return valid && realConnection != null && dataSource.pingConnection(this);
    }

看这个方法的实现代码,最终还是调用PooledDataSource的pingConnection()方法

protected boolean pingConnection(PooledConnection conn) {
        boolean result = true; 

        try {
            result = !conn.getRealConnection().isClosed();
        } catch (SQLException e) {
            if (log.isDebugEnabled()) {
                log.debug("Connection " + conn.getRealHashCode() + " is BAD: " + e.getMessage());
            }
            result = false;
        }

        
        if (result && poolPingEnabled && poolPingConnectionsNotUsedFor >= 0
                && conn.getTimeElapsedSinceLastUse() > poolPingConnectionsNotUsedFor) {
            try {
                if (log.isDebugEnabled()) {
                    log.debug("Testing connection " + conn.getRealHashCode() + " ...");
                }
                Connection realConn = conn.getRealConnection();
                try (Statement statement = realConn.createStatement()) {
                    statement.executeQuery(poolPingQuery).close();
                }
                if (!realConn.getAutoCommit()) {
                    realConn.rollback();
                }
                result = true; 
                if (log.isDebugEnabled()) {
                    log.debug("Connection " + conn.getRealHashCode() + " is GOOD!");
                }
            } catch (Exception e) {
                log.warn("Execution of ping query '" + poolPingQuery + "' failed: " + e.getMessage());
                try {
                    conn.getRealConnection().close();
                } catch (Exception e2) {
                    // ignore
                }
                result = false;  
                if (log.isDebugEnabled()) {
                    log.debug("Connection " + conn.getRealHashCode() + " is BAD: " + e.getMessage());
                }
            }
        }
        return result;
    }
    
  1. 首先检测是否关闭了连接,如果关闭返回false
  2. 如果没有关闭连接,并且配置中开启了ping连接池的功能,而且连接超过一定时长未使用,这时候通过执行poolPingQuery定义的sql来检测连接是否可用,如果没有异常就返回true,否则返回false

总结

这篇文章主要介绍了聊聊Mybatis的数据源PooledDataSource类一些方法,包括获取数据库连接的方法getConnection(),方法中调用了popConnection(),逻辑是先从空闲连接集合中获取连接信息,如果空闲集合中没有并活跃的连接数没有达到上限的时候就可以创建新的数据库连接,如果达到上限了就判断是否有超时的连接,如果有的话就利用这个超时连接创建新的连接并把超级连接设置为无效,如果超时连接也没有,这时候就调用wait方法进行阻塞,然后分析了一下isValid()方法,这个方法是检测数据库连接是否可用,逻辑是通过执行sql语句来判断的。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。