tomcat jdbc数据库连接池详解之获取连接

编程入门 行业动态 更新时间:2024-10-07 18:21:19

tomcat jdbc数据库连接池<a href=https://www.elefans.com/category/jswz/34/1770044.html style=详解之获取连接"/>

tomcat jdbc数据库连接池详解之获取连接

数据库连接是一种宝贵资源,其建立过程需要tcp握手以及登录校验(验证用户名、密码),这也是一个比较昂贵的过程,如果不使用数据库连接池技术,频繁的创建连接、释放连接将会对系统性能有很大影响。那么数据库连接池是怎样高效的返回连接并管理这些创建好的数据库连接的呢?

本文要讲述的内容涉及到org.apache.tomcat.jdbc.pool.ConnectionPool类以及相关的两个属性:

    private BlockingQueue<PooledConnection> busy;
    private BlockingQueue<PooledConnection> idle;

    public Connection getConnection() throws SQLException {//check out a connectionPooledConnection con = borrowConnection(-1,null,null);//设置该连接,设置JdbcInterceptor调用链return setupConnection(con);}

这就是tomcat jdbc连接池返回数据库连接的地方:

1.先从连接池从“借”一个连接(如果idle队列没有剩余连接则根据实际情况决定是否要创建新的连接)

2.初始化该连接

    private PooledConnection borrowConnection(int wait, String username, String password) throws SQLException {if (isClosed()) {throw new SQLException("Connection pool closed.");} //end if//get the current time stamplong now = System.currentTimeMillis();//see if there is one available immediatelyPooledConnection con = idle.poll();while (true) {if (con!=null) {//configure the connection and return it//这里返回的连接会被加入到busy队列中,而returnConnection则会将busy中的连接移除并根据实际情况决定是否需要添加到idle队列中PooledConnection result = borrowConnection(now, con, username, password);borrowedCount.incrementAndGet();if (result!=null) return result;}//if we get here, see if we need to create one//this is not 100% accurate since it doesn't use a shared//atomic variable - a connection can become idle while we are creating//a new connectionif (size.get() < getPoolProperties().getMaxActive()) {//atomic duplicate checkif (size.addAndGet(1) > getPoolProperties().getMaxActive()) {//if we got here, two threads passed through the first ifsize.decrementAndGet();} else {//create a connection, we're below the limitreturn createConnection(now, con, username, password);}} //end if//calculate wait time for this iterationlong maxWait = wait;//if the passed in wait time is -1, means we should use the pool property valueif (wait==-1) {maxWait = (getPoolProperties().getMaxWait()<=0)?Long.MAX_VALUE:getPoolProperties().getMaxWait();}long timetowait = Math.max(0, maxWait - (System.currentTimeMillis() - now));waitcount.incrementAndGet();try {//retrieve an existing connectioncon = idle.poll(timetowait, TimeUnit.MILLISECONDS);} catch (InterruptedException ex) {if (getPoolProperties().getPropagateInterruptState()) {Thread.currentThread().interrupt();}SQLException sx = new SQLException("Pool wait interrupted.");sx.initCause(ex);throw sx;} finally {waitcount.decrementAndGet();}if (maxWait==0 && con == null) { //no wait, return one if we have oneif (jmxPool!=null) {jmxPool.notify(org.apache.tomcat.jdbc.pool.jmx.ConnectionPool.POOL_EMPTY, "Pool empty - no wait.");}throw new PoolExhaustedException("[" + Thread.currentThread().getName()+"] " +"NoWait: Pool empty. Unable to fetch a connection, none available["+busy.size()+" in use].");}//we didn't get a connection, lets see if we timed outif (con == null) {if ((System.currentTimeMillis() - now) >= maxWait) {if (jmxPool!=null) {jmxPool.notify(org.apache.tomcat.jdbc.pool.jmx.ConnectionPool.POOL_EMPTY, "Pool empty - timeout.");}throw new PoolExhaustedException("[" + Thread.currentThread().getName()+"] " +"Timeout: Pool empty. Unable to fetch a connection in " + (maxWait / 1000) +" seconds, none available[size:"+size.get() +"; busy:"+busy.size()+"; idle:"+idle.size()+"; lastwait:"+timetowait+"].");} else {//no timeout, lets try againcontinue;}}} //while}

 

以上就是tomcat jdbc连接池返回连接的大致流程,感兴趣的可以打开ConnectionPool的源码进一步分析

更多推荐

tomcat jdbc数据库连接池详解之获取连接

本文发布于:2024-02-14 12:25:21,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1763076.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:详解   数据库   连接池   tomcat   jdbc

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!