DruidPooledConnection 源码解析

今天的代码比较易懂

//下面是创建拿到连接之后,创建Statement的逻辑

public void checkState() throws SQLException {
    final boolean asyncCloseEnabled;
    if (holder != null) {
        //判断连接是否关闭
        asyncCloseEnabled = holder.getDataSource().isAsyncCloseConnectionEnable();
    } else {
        asyncCloseEnabled = false;
    }

    if (asyncCloseEnabled) {
        lock.lock();
        try {
            checkStateInternal();
        } finally {
            lock.unlock();
        }
    } else {
        checkStateInternal();
    }
}
void initStatement(DruidPooledConnection conn, Statement stmt) throws SQLException {
    // transaction: 事务是否是自动提交
    boolean transaction = !conn.getConnectionHolder().underlyingAutoCommit;
    // queryTimeout: 超时时间
    int queryTimeout = transaction ? getTransactionQueryTimeout() : getQueryTimeout();

    if (queryTimeout > 0) {
        stmt.setQueryTimeout(queryTimeout);
    }
}

public Statement createStatement() throws SQLException {
    //1.上来要先检察一下连接是否可用
    checkState();

    Statement stmt = null;
    try {
        stmt = conn.createStatement();
    } catch (SQLException ex) {
        handleException(ex, null);
    }

    holder.getDataSource().initStatement(this, stmt);

    DruidPooledStatement poolableStatement = new DruidPooledStatement(this, stmt);
    //List<Statement>  缓存到到这个list中
    holder.addTrace(poolableStatement);

    return poolableStatement;
}

protected void transactionRecord(String sql) throws SQLException {
    if (holder != null) {
        holder.setLastExecTimeMillis(System.currentTimeMillis());
    }

    if (transactionInfo == null && (!conn.getAutoCommit())) {
        //
        DruidAbstractDataSource dataSource = holder.getDataSource();
        //统计transactionCount的数量
        dataSource.incrementStartTransactionCount();
        transactionInfo = new TransactionInfo(dataSource.createTransactionId());
    }

    if (transactionInfo != null) {
        //在connection上绑定transactionInfo的属性,在transactionInfo中包含sql语句
        List<String> sqlList = transactionInfo.getSqlList();
        if (sqlList.size() < MAX_RECORD_SQL_COUNT) {
            sqlList.add(sql);
        }
    }
}
//查询
public final ResultSet executeQuery(String sql) throws SQLException {
    checkOpen();
    //
    incrementExecuteQueryCount();
    transactionRecord(sql);

    conn.beforeExecute();
    try {
        ResultSet rs = stmt.executeQuery(sql);

        if (rs == null) {
            return rs;
        }

        DruidPooledResultSet poolableResultSet = new DruidPooledResultSet(this, rs);
        //
        addResultSetTrace(poolableResultSet);

        return poolableResultSet;
    } catch (Throwable t) {
        errorCheck(t);

        throw checkException(t, sql);
    } finally {
        conn.afterExecute();
    }
}
protected void addResultSetTrace(ResultSet resultSet) {
    if (resultSetTrace == null) {
        resultSetTrace = new ArrayList<ResultSet>(1);
    } else if (resultSetTrace.size() > 0) {
        int lastIndex = resultSetTrace.size() - 1;
        ResultSet lastResultSet = resultSetTrace.get(lastIndex);
        try {
            if (lastResultSet.isClosed()) {
                resultSetTrace.set(lastIndex, resultSet);
                return;
            }
        } catch (SQLException ex) {
            // skip
        }
    }
    //缓存resultSetTrace
    resultSetTrace.add(resultSet);
}

//通过以上的方法拿到查询语句.查询完关闭连接

protected void recycle(DruidPooledConnection pooledConnection) throws SQLException {
    final DruidConnectionHolder holder = pooledConnection.holder;

    if (holder == null) {
        LOG.warn("connectionHolder is null");
        return;
    }

    if (logDifferentThread //
        && (!isAsyncCloseConnectionEnable()) //
        && pooledConnection.ownerThread != Thread.currentThread()//
    ) {
        LOG.warn("get/close not same thread");
    }

    final Connection physicalConnection = holder.conn;

    if (pooledConnection.traceEnable) {
        Object oldInfo = null;
        activeConnectionLock.lock();
        try {
            if (pooledConnection.traceEnable) {
                oldInfo = activeConnections.remove(pooledConnection);
                pooledConnection.traceEnable = false;
            }
        } finally {
            activeConnectionLock.unlock();
        }
        if (oldInfo == null) {
            if (LOG.isWarnEnabled()) {
                LOG.warn("remove abandonded failed. activeConnections.size " + activeConnections.size());
            }
        }
    }

    final boolean isAutoCommit = holder.underlyingAutoCommit;
    final boolean isReadOnly = holder.underlyingReadOnly;
    final boolean testOnReturn = this.testOnReturn;

    try {
        // check need to rollback?
        if ((!isAutoCommit) && (!isReadOnly)) {
            pooledConnection.rollback();
        }

        // reset holder, restore default settings, clear warnings
        boolean isSameThread = pooledConnection.ownerThread == Thread.currentThread();
        if (!isSameThread) {
            final ReentrantLock lock = pooledConnection.lock;
            lock.lock();
            try {
                holder.reset();
            } finally {
                lock.unlock();
            }
        } else {
            holder.reset();
        }

        if (holder.discard) {
            return;
        }

        if (phyMaxUseCount > 0 && holder.useCount >= phyMaxUseCount) {
            discardConnection(holder);
            return;
        }

        if (physicalConnection.isClosed()) {
            lock.lock();
            try {
                if (holder.active) {
                    activeCount--;
                    holder.active = false;
                }
                closeCount++;
            } finally {
                lock.unlock();
            }
            return;
        }

        if (testOnReturn) {
            boolean validate = testConnectionInternal(holder, physicalConnection);
            if (!validate) {
                JdbcUtils.close(physicalConnection);

                destroyCountUpdater.incrementAndGet(this);

                lock.lock();
                try {
                    if (holder.active) {
                        activeCount--;
                        holder.active = false;
                    }
                    closeCount++;
                } finally {
                    lock.unlock();
                }
                return;
            }
        }
        if (holder.initSchema != null) {
            holder.conn.setSchema(holder.initSchema);
            holder.initSchema = null;
        }

        if (!enable) {
            discardConnection(holder);
            return;
        }

        boolean result;
        final long currentTimeMillis = System.currentTimeMillis();

        if (phyTimeoutMillis > 0) {
            long phyConnectTimeMillis = currentTimeMillis - holder.connectTimeMillis;
            if (phyConnectTimeMillis > phyTimeoutMillis) {
                discardConnection(holder);
                return;
            }
        }

        lock.lock();
        try {
            if (holder.active) {
                activeCount--;
                holder.active = false;
            }
            closeCount++;

            result = putLast(holder, currentTimeMillis);
            recycleCount++;
        } finally {
            lock.unlock();
        }

        if (!result) {
            JdbcUtils.close(holder.conn);
            LOG.info("connection recyle failed.");
        }
    } catch (Throwable e) {
        holder.clearStatementCache();

        if (!holder.discard) {
            discardConnection(holder);
            holder.discard = true;
        }

        LOG.error("recyle error", e);
        recycleErrorCountUpdater.incrementAndGet(this);
    }
}

    

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值