S2DBCPのコネクションプーリングの実装を読んでみた

Slim3とは異なりS2DBCP でプーリングされるのは物理コネクション (XAConnection) ではなくて論理コネクション (Connection) ね。あとConnectionEventListenerの仕掛けは使ってない。JDBCの仕様書をぱらっと見る限りSlim3のほうが素直に実装している感じ。

DataSource(実態はDataSourceImplでコネクションプーリングを実現しているConnectionPoolImplの薄いラッパー)#getConnectionが呼ばれるとあとはConnectionPoolImpl#checkOutにおまかせ。

    public Connection getConnection() throws SQLException {
        Connection con = connectionPool.checkOut();
        return con;
    }

checkOut では、getTransaction()でThreadLocalからトランザクションをとってきて、その後getConnectionTxActivePoolでトランザクションにひもづく論理コネクションをとってくる。
(txActivePoolフィールド(型はMap)でキーにトランザクション、バリューに論理コネクションを関連づけている。Slim3だとトランザクションも物理コネクションもThreadLocalで管理している。)
コネクションが無ければプールからとってくるか、プールが空なら新規作成する。あとはSlim3と同じかな。

    public synchronized ConnectionWrapper checkOut() throws SQLException {
        Transaction tx = getTransaction();
        if (tx == null && !isAllowLocalTx()) {
            throw new SIllegalStateException("ESSR0311", null);
        }

        ConnectionWrapper con = getConnectionTxActivePool(tx);
        if (con != null) {
            if (logger.isDebugEnabled()) {
                logger.log("DSSR0007", new Object[] { tx });
            }
            return con;
        }
        while (getMaxPoolSize() > 0
                && getActivePoolSize() + getTxActivePoolSize() >= getMaxPoolSize()) {
            try {
                wait();
            } catch (InterruptedException ignore) {
            }
        }
        con = checkOutFreePool(tx);
        if (con == null) {
            con = createConnection(tx);
        }
        if (tx == null) {
            setConnectionActivePool(con);
        } else {
            TransactionUtil.enlistResource(tx, con.getXAResource());
            TransactionUtil.registerSynchronization(tx,
                    new SynchronizationImpl(tx));
            setConnectionTxActivePool(tx, con);
        }
        con.setReadOnly(readOnly);
        if (transactionIsolationLevel != DEFAULT_TRANSACTION_ISOLATION_LEVEL) {
            con.setTransactionIsolation(transactionIsolationLevel);
        }
        if (logger.isDebugEnabled()) {
            logger.log("DSSR0007", new Object[] { tx });
        }
        return con;
    }

コネクション(ConnectionWrapperImpl)がcloseされるとプールにもどります。

    public void close() throws SQLException {
        if (closed_) {
            return;
        }
        if (logger_.isDebugEnabled()) {
            logger_.log("DSSR0002", new Object[] { tx_ });
        }
        if (tx_ == null) {
            connectionPool_.checkIn(this);
        } else {
            connectionPool_.checkInTx(tx_);
        }
    }

参考