MyBatis官方文档

介绍

  • This is a simple, synchronous, thread-safe database connection pool.

源码

成员方法

private static final Log log = LogFactory.getLog(PooledDataSource.class);

 private final PoolState state = new PoolState(this);

 private final UnpooledDataSource dataSource;

 // OPTIONAL CONFIGURATION FIELDS
 protected int poolMaximumActiveConnections = 10;
 protected int poolMaximumIdleConnections = 5;
 protected int poolMaximumCheckoutTime = 20000;
 protected int poolTimeToWait = 20000;
 protected int poolMaximumLocalBadConnectionTolerance = 3;
 protected String poolPingQuery = "NO PING QUERY SET";
 protected boolean poolPingEnabled;
 protected int poolPingConnectionsNotUsedFor;

 private int expectedConnectionTypeCode;

成员方法

 /*
  * Closes all active and idle connections in the pool
  */
 public void forceCloseAll() {
 // synchronized 给对象加锁
   synchronized (state) {
     expectedConnectionTypeCode = assembleConnectionTypeCode(dataSource.getUrl(), dataSource.getUsername(), dataSource.getPassword());
     for (int i = state.activeConnections.size(); i > 0; i--) {
       try {
         PooledConnection conn = state.activeConnections.remove(i - 1);
         conn.invalidate();

         Connection realConn = conn.getRealConnection();
         if (!realConn.getAutoCommit()) {
           realConn.rollback();
         }
         realConn.close();
       } catch (Exception e) {
         // ignore
       }
     }
     for (int i = state.idleConnections.size(); i > 0; i--) {
       try {
         PooledConnection conn = state.idleConnections.remove(i - 1);
         conn.invalidate();

         Connection realConn = conn.getRealConnection();
         if (!realConn.getAutoCommit()) {
           realConn.rollback();
         }
         realConn.close();
       } catch (Exception e) {
         // ignore
       }
     }
   }
   if (log.isDebugEnabled()) {
     log.debug("PooledDataSource forcefully closed/removed all connections.");
   }
 }

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++;
    }
  }
}
10-04 20:37