最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Mybatis中的PooledDataSource

 更新時間:2022年06月13日 14:16:01   作者:周杰倫本人  
這篇文章主要介紹了詳解Mybatis中的PooledDataSource,PooledDataSource使用了數(shù)據(jù)庫連接池可以實(shí)現(xiàn)數(shù)據(jù)庫連接池的重復(fù)利用,還能控制連接數(shù)據(jù)庫的連接上限

前言

上篇Java Mybatis數(shù)據(jù)源之工廠模式文章中我們介紹了Mybatis的數(shù)據(jù)源模塊的DataSource接口和它對應(yīng)的實(shí)現(xiàn)類UnpooledDataSource、PooledDataSource,這篇文章詳細(xì)介紹一下PooledDataSource
PooledDataSource使用了數(shù)據(jù)庫連接池可以實(shí)現(xiàn)數(shù)據(jù)庫連接池的重復(fù)利用,還能控制連接數(shù)據(jù)庫的連接上限,實(shí)現(xiàn)數(shù)據(jù)庫連接的統(tǒng)一管理,緩存數(shù)據(jù)連接信息還能防止流量突發(fā)連接數(shù)據(jù)庫不及時

PooledDataSource有個PoolState狀態(tài),PoolState里保存著數(shù)據(jù)庫連接信息PooledConnection,PooledConnection實(shí)現(xiàn)InvocationHandler接口,重寫invoke方法,顯然這是一個代理類,使用了JDK的動態(tài)代理

PooledConnection

   class PooledConnection implements InvocationHandler {
    private static final Class<?>[] IFACES = new Class<?>[] { Connection.class };
    public PooledConnection(Connection connection, PooledDataSource dataSource) {
        this.hashCode = connection.hashCode();
        this.realConnection = connection;
        this.dataSource = dataSource;
        this.createdTimestamp = System.currentTimeMillis();
        this.lastUsedTimestamp = System.currentTimeMillis();
        this.valid = true;
        this.proxyConnection = (Connection) Proxy.newProxyInstance(Connection.class.getClassLoader(), IFACES, this);
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String methodName = method.getName();
        if (CLOSE.equals(methodName)) {
            dataSource.pushConnection(this);
            return null;
        }
        try {
            if (!Object.class.equals(method.getDeclaringClass())) {
                checkConnection();
            }
            return method.invoke(realConnection, args);
        } catch (Throwable t) {
            throw ExceptionUtil.unwrapThrowable(t);
        }
    }
}

我們看一看到構(gòu)造方法中調(diào)用了Proxy.newProxyInstance()方法來生成代理類,而重寫invoke方法中如果是close()就調(diào)用pushConnection()方法直接把它放入連接池而不是關(guān)閉連接,其他情況調(diào)用checkConnection()檢查連接信息,代理類調(diào)用realConnection()方法,下面就看一下pushConnection()方法

PooledDataSource的pushConnection()方法

方法的功能就是把數(shù)據(jù)庫連接放入連接池中:

protected void pushConnection(PooledConnection conn) throws SQLException {
        synchronized (state) {
            state.activeConnections.remove(conn);
            if (conn.isValid()) {
                if (state.idleConnections.size() < poolMaximumIdleConnections && conn.getConnectionTypeCode() == expectedConnectionTypeCode) {
                    state.accumulatedCheckoutTime += conn.getCheckoutTime();
                    if (!conn.getRealConnection().getAutoCommit()) {
                        conn.getRealConnection().rollback();
                    }
                    PooledConnection newConn = new PooledConnection(conn.getRealConnection(), this);
                    state.idleConnections.add(newConn);
                    newConn.setCreatedTimestamp(conn.getCreatedTimestamp());
                    newConn.setLastUsedTimestamp(conn.getLastUsedTimestamp());
                    conn.invalidate(); 
                    if (log.isDebugEnabled()) {
                        log.debug("Returned connection " + newConn.getRealHashCode() + " to pool.");
                    }
                    state.notifyAll();
                } else {

                    state.accumulatedCheckoutTime += conn.getCheckoutTime();
                    if (!conn.getRealConnection().getAutoCommit()) {
                        conn.getRealConnection().rollback();
                    }
                    conn.getRealConnection().close();
                    if (log.isDebugEnabled()) {
                        log.debug("Closed connection " + conn.getRealHashCode() + ".");
                    }
                    conn.invalidate();
                }
            } else {
                if (log.isDebugEnabled()) {
                    log.debug("A bad connection (" + conn.getRealHashCode() + ") attempted to return to the pool, discarding connection.");
                }
                state.badConnectionCount++;
            }
        }
    }
  • 從活躍連接集合中刪除該連接
  • 如果PooledConnection有效,并且空閑連接數(shù)小于最大空閑連接數(shù),就利用當(dāng)前PooledConnection創(chuàng)建PooledConnection,放入空閑連接數(shù)集合中,方便下次使用,關(guān)閉當(dāng)前PooledConnection對象的數(shù)據(jù)庫連接,并對當(dāng)前PooledConnection對象設(shè)置無效,最后喚醒其他等待的線程。如果空閑連接數(shù)大于最大空閑連接數(shù)了就關(guān)閉連接,設(shè)置當(dāng)前連接無效
  • 如果PooledConnection無效,badConnectionCount加一,這個badConnectionCount是記錄無效的數(shù)據(jù)庫連接信息的

總結(jié)

本篇文章主要介紹了PooledConnection和PooledDataSource的pushConnection()方法,PooledConnection用到了jdk的動態(tài)代理,生成Connection的實(shí)現(xiàn)類的代理類,攔截的邏輯中對于close()方法沒有真正關(guān)閉,而是把數(shù)據(jù)庫連接信息放入連接池中供下次再使用,數(shù)據(jù)庫連接信息放入連接池的過程是通過調(diào)用PooledDataSource的pushConnection()來完成的,具體就是從活躍連接集合中刪除這個連接,然后放入空閑連接數(shù)集合中并把當(dāng)前連接設(shè)置為無效。

到此這篇關(guān)于詳解Mybatis中的PooledDataSource的文章就介紹到這了,更多相關(guān)Mybatis PooledDataSource內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

平南县| 兴城市| 汤原县| 上思县| 陆良县| 若尔盖县| 东莞市| 南雄市| 安庆市| 太白县| 西丰县| 松溪县| 静宁县| 恩施市| 托里县| 奎屯市| 晋城| 北票市| 莱西市| 上栗县| 丹凤县| 旬阳县| 嘉禾县| 开阳县| 霍山县| 繁峙县| 社会| 航空| 堆龙德庆县| 吴江市| 紫云| 施甸县| 余干县| 维西| 西宁市| 都兰县| 获嘉县| 徐州市| 临湘市| 南昌市| 胶州市|