Mybatis数据源与数据库连接池

现在让我们看一下popConnection()方法到底做了什么:

1.  先看是否有空闲(idle)状态下的PooledConnection对象,如果有,就直接返回一个可用的PooledConnection对象;否则进行第2步。

2.  查看活动状态的PooledConnection池activeConnections是否已满;如果没有满,则创建一个新的PooledConnection对象,然后放到activeConnections池中,然后返回此PooledConnection对象;否则进行第三步;

3.  看最先进入activeConnections池中的PooledConnection对象是否已经过期:如果已经过期,从activeConnections池中移除此对象,然后创建一个新的PooledConnection对象,添加到activeConnections中,然后将此对象返回;否则进行第4步。

4.  线程等待,循环2步

[java] view plain copy

  

  1. /* 
  2.  * 传递一个用户名和密码,从连接池中返回可用的PooledConnection 
  3.  */  
  4. private PooledConnection popConnection(String username, String password) throws SQLException  
  5. {  
  6.     boolean countedWait = false;  
  7.     PooledConnection conn = null;  
  8.     long t = System.currentTimeMillis();  
  9.     int localBadConnectionCount = 0;  
  10.   
  11.     while (conn == null)  
  12.     {  
  13.         synchronized (state)  
  14.         {  
  15.             if (state.idleConnections.size() > 0)  
  16.             {  
  17.                 // 连接池中有空闲连接,取出第一个  
  18.                 conn = state.idleConnections.remove(0);  
  19.                 if (log.isDebugEnabled())  
  20.                 {  
  21.                     log.debug("Checked out connection " + conn.getRealHashCode() + " from pool.");  
  22.                 }  
  23.             }  
  24.             else  
  25.             {  
  26.                 // 连接池中没有空闲连接,则取当前正在使用的连接数小于最大限定值,  
  27.                 if (state.activeConnections.size() < poolMaximumActiveConnections)  
  28.                 {  
  29.                     // 创建一个新的connection对象  
  30.                     conn = new PooledConnection(dataSource.getConnection(), this);  
  31.                     @SuppressWarnings("unused")  
  32.                     //used in logging, if enabled  
  33.                     Connection realConn = conn.getRealConnection();  
  34.                     if (log.isDebugEnabled())  
  35.                     {  
  36.                         log.debug("Created connection " + conn.getRealHashCode() + ".");  
  37.                     }  
  38.                 }  
  39.                 else  
  40.                 {  
  41.                     // Cannot create new connection 当活动连接池已满,不能创建时,取出活动连接池的第一个,即最先进入连接池的PooledConnection对象  
  42.                     // 计算它的校验时间,如果校验时间大于连接池规定的最大校验时间,则认为它已经过期了,利用这个PoolConnection内部的realConnection重新生成一个PooledConnection  
  43.                     //  
  44.                     PooledConnection oldestActiveConnection = state.activeConnections.get(0);  
  45.                     long longestCheckoutTime = oldestActiveConnection.getCheckoutTime();  
  46.                     if (longestCheckoutTime > poolMaximumCheckoutTime)  
  47.                     {  
  48.                         // Can claim overdue connection  
  49.                         state.claimedOverdueConnectionCount++;  
  50.                         state.accumulatedCheckoutTimeOfOverdueConnections += longestCheckoutTime;  
  51.                         state.accumulatedCheckoutTime += longestCheckoutTime;  
  52.                         state.activeConnections.remove(oldestActiveConnection);  
  53.                         if (!oldestActiveConnection.getRealConnection().getAutoCommit())  
  54.                         {  
  55.                             oldestActiveConnection.getRealConnection().rollback();  
  56.                         }  
  57.                         conn = new PooledConnection(oldestActiveConnection.getRealConnection(), this);  
  58.                         oldestActiveConnection.invalidate();  
  59.                         if (log.isDebugEnabled())  
  60.                         {  
  61.                             log.debug("Claimed overdue connection " + conn.getRealHashCode() + ".");  
  62.                         }  
  63.                     }  
  64.                     else  
  65.                     {  
  66.   
  67.                         //如果不能释放,则必须等待有  
  68.                         // Must wait  
  69.                         try  
  70.                         {  
  71.                             if (!countedWait)  
  72.                             {  
  73.                                 state.hadToWaitCount++;  
  74.                                 countedWait = true;  
  75.                             }  
  76.                             if (log.isDebugEnabled())  
  77.                             {  
  78.                                 log.debug("Waiting as long as " + poolTimeToWait + " milliseconds for connection.");  
  79.                             }  
  80.                             long wt = System.currentTimeMillis();  
  81.                             state.wait(poolTimeToWait);  
  82.                             state.accumulatedWaitTime += System.currentTimeMillis() - wt;  
  83.                         }  
  84.                         catch (InterruptedException e)  
  85.                         {  
  86.                             break;  
  87.                         }  
  88.                     }  
  89.                 }  
  90.             }  
  91.   
  92.             //如果获取PooledConnection成功,则更新其信息  
  93.   
  94.             if (conn != null)  
  95.             {  
  96.                 if (conn.isValid())  
  97.                 {  
  98.                     if (!conn.getRealConnection().getAutoCommit())  
  99.                     {  
  100.                         conn.getRealConnection().rollback();  
  101.                     }  
  102.                     conn.setConnectionTypeCode(assembleConnectionTypeCode(dataSource.getUrl(), username, password));  
  103.                     conn.setCheckoutTimestamp(System.currentTimeMillis());  
  104.                     conn.setLastUsedTimestamp(System.currentTimeMillis());  
  105.                     state.activeConnections.add(conn);  
  106.                     state.requestCount++;  
  107.                     state.accumulatedRequestTime += System.currentTimeMillis() - t;  
  108.                 }  
  109.                 else  
  110.                 {  
  111.                     if (log.isDebugEnabled())  
  112.                     {  
  113.                         log.debug("A bad connection (" + conn.getRealHashCode() + ") was returned from the pool, getting another connection.");  
  114.                     }  
  115.                     state.badConnectionCount++;  
  116.                     localBadConnectionCount++;  
  117.                     conn = null;  
  118.                     if (localBadConnectionCount > (poolMaximumIdleConnections + 3))  
  119.                     {  
  120.                         if (log.isDebugEnabled())  
  121.                         {  
  122.                             log.debug("PooledDataSource: Could not get a good connection to the database.");  
  123.                         }  
  124.                         throw new SQLException("PooledDataSource: Could not get a good connection to the database.");  
  125.                     }  
  126.                 }  
  127.             }  
  128.         }  
  129.   
  130.     }  
  131.   
  132.     if (conn == null)  
  133.     {  
  134.         if (log.isDebugEnabled())  
  135.         {  
  136.             log.debug("PooledDataSource: Unknown severe error condition.  The connection pool returned a null connection.");  
  137.         }  
  138.         throw new SQLException("PooledDataSource: Unknown severe error condition.  The connection pool returned a null connection.");  
  139.     }  
  140.   
  141.     return conn;  
  142. }  

对应的处理流程图如下所示:

如上所示,对于PooledDataSource的getConnection()方法内,先是调用类PooledDataSource的popConnection()方法返回了一个PooledConnection对象,然后调用了PooledConnection的getProxyConnection()来返回Connection对象。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值