Mybatis POOLED和UNPOOLED源码解析

1.UNPOOLED

下面UnpooledDataSource getConnection源码

public Connection getConnection() throws SQLException {
        return this.doGetConnection(this.username, this.password);
    }
    private Connection doGetConnection(String username, String password) throws SQLException {
        Properties props = new Properties();
        if (this.driverProperties != null) {
            props.putAll(this.driverProperties);
        }

        if (username != null) {
            props.setProperty("user", username);
        }

        if (password != null) {
            props.setProperty("password", password);
        }

        return this.doGetConnection(props);
    }

在这个方法中先创建了一个Properties对象,这个对象是用来专门配置属性的对象,在这之后添加了配置数据库连接的username和password属性,并调用了doGetConnection方法,并传入了props对象;

    private Connection doGetConnection(Properties properties) throws SQLException {
        this.initializeDriver();
        Connection connection = DriverManager.getConnection(this.url, properties);
        this.configureConnection(connection);
        return connection;
    }

这个方法就比较清楚,首先大概能猜到第一行initializeDriver()在注册驱动

private synchronized void initializeDriver() throws SQLException {
        if (!registeredDrivers.containsKey(this.driver)) {
            try {
                Class driverType;
                if (this.driverClassLoader != null) {
                    driverType = Class.forName(this.driver, true, this.driverClassLoader);
                } else {
                    driverType = Resources.classForName(this.driver);
                }

                Driver driverInstance = (Driver)driverType.newInstance();
                DriverManager.registerDriver(new UnpooledDataSource.DriverProxy(driverInstance));
                registeredDrivers.put(this.driver, driverInstance);
            } catch (Exception var3) {
                throw new SQLException("Error setting driver on UnpooledDataSource. Cause: " + var3);
            }
        }

    }

确实,这个方法实在注册驱动

第二行就是获取connection了,后面就直接返回了。

2.POOLED

在getConnection中调用了popConnection

 public Connection getConnection() throws SQLException {
        return this.popConnection(this.dataSource.getUsername(), this.dataSource.getPassword()).getProxyConnection();
    }

下面来分析一下popConnection方法的源码

首先,获取连接必须保证线程安全,所以带上synchronized代码块

synchronized(this.state) {

下一句,判断是否在线程池中是否由空闲连接

if (!this.state.idleConnections.isEmpty()) {

如果有,就直接从线程池中获取第一个

conn = (PooledConnection)this.state.idleConnections.remove(0);

这里的idleConnections就是一个放置连接的集合

protected final List<PooledConnection> idleConnections = new ArrayList();

如果没有,判断另外一个已使用池中的最大连接数量是否大于当前的使用连接数量

else if (this.state.activeConnections.size() < this.poolMaximumActiveConnections) 

如果大于,就在创建一个连接进行返回

 conn = new PooledConnection(this.dataSource.getConnection(), this);

如果空闲池为空,使用池的连接数也已达到最大使用连接数,就从使用池中取出一个最久的连接,也就是最早的连接,清空属性保证它是一个纯净的连接后返回

PooledConnection oldestActiveConnection = (PooledConnection)this.state.activeConnections.get(0);
                    long longestCheckoutTime = oldestActiveConnection.getCheckoutTime();
                    if (longestCheckoutTime > (long)this.poolMaximumCheckoutTime) {
                        ++this.state.claimedOverdueConnectionCount;
                        var10000 = this.state;
                        var10000.accumulatedCheckoutTimeOfOverdueConnections += longestCheckoutTime;
                        var10000 = this.state;
                        var10000.accumulatedCheckoutTime += longestCheckoutTime;
                        this.state.activeConnections.remove(oldestActiveConnection);
                        if (!oldestActiveConnection.getRealConnection().getAutoCommit()) {
                            try {
                                oldestActiveConnection.getRealConnection().rollback();
                            } catch (SQLException var16) {
                                log.debug("Bad connection. Could not roll back");
                            }
                        }

                        conn = new PooledConnection(oldestActiveConnection.getRealConnection(), this);
                        conn.setCreatedTimestamp(oldestActiveConnection.getCreatedTimestamp());
                        conn.setLastUsedTimestamp(oldestActiveConnection.getLastUsedTimestamp());
                        oldestActiveConnection.invalidate();
                        if (log.isDebugEnabled()) {
                            log.debug("Claimed overdue connection " + conn.getRealHashCode() + ".");
                        }
                    } else {
                        try {
                            if (!countedWait) {
                                ++this.state.hadToWaitCount;
                                countedWait = true;
                            }

                            if (log.isDebugEnabled()) {
                                log.debug("Waiting as long as " + this.poolTimeToWait + " milliseconds for connection.");
                            }

                            long wt = System.currentTimeMillis();
                            this.state.wait((long)this.poolTimeToWait);
                            var10000 = this.state;
                            var10000.accumulatedWaitTime += System.currentTimeMillis() - wt;
                        } catch (InterruptedException var17) {
                            break;
                        }

 

总结

POOLED采用的是连接池的方式,而UNPOOLED则采用是单独获取一个连接的方式

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值