0
点赞
收藏
分享

微信扫一扫

聊聊Mybatis的数据源之PooledDataSource(二)

@[TOC]

聊聊Mybatis的数据源之PooledDataSource(二)

看完PooledDataSource的pushConnection()方法,再看一下它的popConnection()方法:

获取数据库连接

获取数据库的连接调用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语句来判断的。

举报

相关推荐

0 条评论