コード例 #1
0
 public PooledDataSource(
     ClassLoader driverClassLoader, String driver, String url, Properties driverProperties) {
   dataSource = new UnpooledDataSource(driverClassLoader, driver, url, driverProperties);
   expectedConnectionTypeCode =
       assembleConnectionTypeCode(
           dataSource.getUrl(), dataSource.getUsername(), dataSource.getPassword());
 }
コード例 #2
0
ファイル: BaseDataTest.java プロジェクト: jxcypress/mybatis
 public static UnpooledDataSource createUnpooledDataSource(String resource) throws IOException {
   Properties props = Resources.getResourceAsProperties(resource);
   UnpooledDataSource ds = new UnpooledDataSource();
   ds.setDriver(props.getProperty("driver"));
   ds.setUrl(props.getProperty("url"));
   ds.setUsername(props.getProperty("username"));
   ds.setPassword(props.getProperty("password"));
   return ds;
 }
コード例 #3
0
  /*
   * Closes all active and idle connections in the pool
   */
  public void forceCloseAll() { // 关闭pool里的所有连接,两个list中的连接都移除且关闭
    synchronized (state) {
      expectedConnectionTypeCode =
          assembleConnectionTypeCode(
              dataSource.getUrl(), dataSource.getUsername(), dataSource.getPassword());
      for (int i = state.activeConnections.size(); i > 0; i--) { // 遍历活动连接list
        try {
          PooledConnection conn = state.activeConnections.remove(i - 1); // 从活动连接list移出
          conn.invalidate(); // PooledConnection的valid设为false

          Connection realConn = conn.getRealConnection(); // 获取真conn (java.sql.Connection)
          if (!realConn.getAutoCommit()) { // 不是自动提交的话
            realConn.rollback(); // 回滚
          }
          realConn.close();
        } catch (Exception e) {
          // ignore
        }
      }
      for (int i = state.idleConnections.size(); i > 0; i--) { // 简历空闲连接list
        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.");
    }
  }
コード例 #4
0
  /*
   * Closes all active and idle connections in the pool
   */
  public void forceCloseAll() {
    synchronized (state) {
      expectedConnectionTypeCode =
          assembleConnectionTypeCode(
              dataSource.getUrl(), dataSource.getUsername(), dataSource.getPassword());
      for (int i = state.activeConnections.size(); i > 0; i--) {
        try {
          PooledConnection conn = (PooledConnection) 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 = (PooledConnection) 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.");
    }
  }
コード例 #5
0
 public Properties getDriverProperties() {
   return dataSource.getDriverProperties();
 }
コード例 #6
0
 public void setDefaultTransactionIsolationLevel(Integer defaultTransactionIsolationLevel) {
   dataSource.setDefaultTransactionIsolationLevel(defaultTransactionIsolationLevel);
   forceCloseAll();
 }
コード例 #7
0
 public boolean isAutoCommit() {
   return dataSource.isAutoCommit();
 }
コード例 #8
0
 public Integer getDefaultTransactionIsolationLevel() {
   return dataSource.getDefaultTransactionIsolationLevel();
 }
コード例 #9
0
 public String getUsername() {
   return dataSource.getUsername();
 }
コード例 #10
0
 public String getPassword() {
   return dataSource.getPassword();
 }
コード例 #11
0
  private PooledConnection popConnection(String username, String password) throws SQLException {
    boolean countedWait = false;
    PooledConnection conn = null;
    long t = System.currentTimeMillis();
    int localBadConnectionCount = 0;

    while (conn == null) {
      synchronized (state) {
        if (state.idleConnections.size() > 0) {
          // Pool has available connection
          conn = (PooledConnection) state.idleConnections.remove(0);
          if (log.isDebugEnabled()) {
            log.debug("Checked out connection " + conn.getRealHashCode() + " from pool.");
          }
        } else {
          // Pool does not have available connection
          if (state.activeConnections.size() < poolMaximumActiveConnections) {
            // Can create new connection
            conn = new PooledConnection(dataSource.getConnection(), this);
            @SuppressWarnings("unused")
            // used in logging, if enabled
            Connection realConn = conn.getRealConnection();
            if (log.isDebugEnabled()) {
              log.debug("Created connection " + conn.getRealHashCode() + ".");
            }
          } else {
            // Cannot create new connection
            PooledConnection oldestActiveConnection =
                (PooledConnection) state.activeConnections.get(0);
            long longestCheckoutTime = oldestActiveConnection.getCheckoutTime();
            if (longestCheckoutTime > poolMaximumCheckoutTime) {
              // Can claim overdue connection
              state.claimedOverdueConnectionCount++;
              state.accumulatedCheckoutTimeOfOverdueConnections += longestCheckoutTime;
              state.accumulatedCheckoutTime += longestCheckoutTime;
              state.activeConnections.remove(oldestActiveConnection);
              if (!oldestActiveConnection.getRealConnection().getAutoCommit()) {
                oldestActiveConnection.getRealConnection().rollback();
              }
              conn = new PooledConnection(oldestActiveConnection.getRealConnection(), this);
              oldestActiveConnection.invalidate();
              if (log.isDebugEnabled()) {
                log.debug("Claimed overdue connection " + conn.getRealHashCode() + ".");
              }
            } else {
              // Must wait
              try {
                if (!countedWait) {
                  state.hadToWaitCount++;
                  countedWait = true;
                }
                if (log.isDebugEnabled()) {
                  log.debug(
                      "Waiting as long as " + poolTimeToWait + " milliseconds for connection.");
                }
                long wt = System.currentTimeMillis();
                state.wait(poolTimeToWait);
                state.accumulatedWaitTime += System.currentTimeMillis() - wt;
              } catch (InterruptedException e) {
                break;
              }
            }
          }
        }
        if (conn != null) {
          if (conn.isValid()) {
            if (!conn.getRealConnection().getAutoCommit()) {
              conn.getRealConnection().rollback();
            }
            conn.setConnectionTypeCode(
                assembleConnectionTypeCode(dataSource.getUrl(), username, password));
            conn.setCheckoutTimestamp(System.currentTimeMillis());
            conn.setLastUsedTimestamp(System.currentTimeMillis());
            state.activeConnections.add(conn);
            state.requestCount++;
            state.accumulatedRequestTime += System.currentTimeMillis() - t;
          } else {
            if (log.isDebugEnabled()) {
              log.debug(
                  "A bad connection ("
                      + conn.getRealHashCode()
                      + ") was returned from the pool, getting another connection.");
            }
            state.badConnectionCount++;
            localBadConnectionCount++;
            conn = null;
            if (localBadConnectionCount > (poolMaximumIdleConnections + 3)) {
              if (log.isDebugEnabled()) {
                log.debug("PooledDataSource: Could not get a good connection to the database.");
              }
              throw new SQLException(
                  "PooledDataSource: Could not get a good connection to the database.");
            }
          }
        }
      }
    }

    if (conn == null) {
      if (log.isDebugEnabled()) {
        log.debug(
            "PooledDataSource: Unknown severe error condition.  The connection pool returned a null connection.");
      }
      throw new SQLException(
          "PooledDataSource: Unknown severe error condition.  The connection pool returned a null connection.");
    }

    return conn;
  }
コード例 #12
0
 public String getUrl() {
   return dataSource.getUrl();
 }
コード例 #13
0
  private PooledConnection popConnection(String username, String password)
      throws SQLException { // 获取一个连接
    boolean countedWait = false;
    PooledConnection conn = null;
    long t = System.currentTimeMillis();
    int localBadConnectionCount = 0;

    while (conn == null) {
      synchronized (state) {
        if (!state.idleConnections.isEmpty()) { // pool里还有空闲连接
          // Pool has available connection
          conn = state.idleConnections.remove(0); // 从空闲list移出一个conn,用做新连接
          if (log.isDebugEnabled()) {
            log.debug("Checked out connection " + conn.getRealHashCode() + " from pool.");
          }
        } else { // pool里没有空闲连接了
          // Pool does not have available connection
          if (state.activeConnections.size() < poolMaximumActiveConnections) { // 活动list没有满
            // Can create new connection
            conn = new PooledConnection(dataSource.getConnection(), this); // 新建一个PooledConnection
            if (log.isDebugEnabled()) {
              log.debug("Created connection " + conn.getRealHashCode() + ".");
            }
          } else { // 活动list已经满了,无法创建新连接
            // Cannot create new connection
            PooledConnection oldestActiveConnection = state.activeConnections.get(0); // 获取最早开始活动的连接
            long longestCheckoutTime =
                oldestActiveConnection.getCheckoutTime(); // 获得最老的活动连接的checkout时间
            if (longestCheckoutTime > poolMaximumCheckoutTime) { // 如果checkout时间大于最大值
              // Can claim overdue connection
              state.claimedOverdueConnectionCount++; // 过期连接计数++
              state.accumulatedCheckoutTimeOfOverdueConnections +=
                  longestCheckoutTime; // 累加过期连接的checkout时间
              state.accumulatedCheckoutTime += longestCheckoutTime; // 累加checkout时间
              state.activeConnections.remove(oldestActiveConnection); // 从活动list移出最老的活动连接,留出空位来啦
              if (!oldestActiveConnection.getRealConnection().getAutoCommit()) {
                oldestActiveConnection.getRealConnection().rollback(); // 回滚
              }
              conn =
                  new PooledConnection(
                      oldestActiveConnection.getRealConnection(), this); // 新建连接,用最老连接的真连接
              oldestActiveConnection.invalidate(); // 最老连接标记无效
              if (log.isDebugEnabled()) {
                log.debug("Claimed overdue connection " + conn.getRealHashCode() + ".");
              }
            } else { // 如果checkout时间并没有超过最大值,必须等待
              // Must wait
              try {
                if (!countedWait) { // countedWait原来是false
                  state.hadToWaitCount++; // 必须等待的计数++
                  countedWait = true; // countedWait变为true
                }
                if (log.isDebugEnabled()) {
                  log.debug(
                      "Waiting as long as " + poolTimeToWait + " milliseconds for connection.");
                }
                long wt = System.currentTimeMillis();
                state.wait(
                    poolTimeToWait); // 等poolTimeToWait微秒,pushConnection移出一个连接时会notifyAll来唤醒wait的线程
                state.accumulatedWaitTime += System.currentTimeMillis() - wt;
              } catch (InterruptedException e) {
                break;
              }
            }
          }
        }
        if (conn != null) { // conn非空,确实建出来了
          if (conn.isValid()) { // conn有效
            if (!conn.getRealConnection().getAutoCommit()) {
              conn.getRealConnection().rollback(); // 这里回滚是干啥? hama
            }
            conn.setConnectionTypeCode(
                assembleConnectionTypeCode(dataSource.getUrl(), username, password));
            conn.setCheckoutTimestamp(System.currentTimeMillis());
            conn.setLastUsedTimestamp(System.currentTimeMillis());
            state.activeConnections.add(conn); // 加入活动list
            state.requestCount++;
            state.accumulatedRequestTime += System.currentTimeMillis() - t;
          } else { // conn无效
            if (log.isDebugEnabled()) {
              log.debug(
                  "A bad connection ("
                      + conn.getRealHashCode()
                      + ") was returned from the pool, getting another connection.");
            }
            state.badConnectionCount++;
            localBadConnectionCount++;
            conn = null;
            if (localBadConnectionCount > (poolMaximumIdleConnections + 3)) {
              if (log.isDebugEnabled()) {
                log.debug("PooledDataSource: Could not get a good connection to the database.");
              }
              throw new SQLException(
                  "PooledDataSource: Could not get a good connection to the database.");
            }
          }
        }
      }
    } // 到这里while结束

    if (conn == null) { // 出现了奇葩的Unknown错吧
      if (log.isDebugEnabled()) {
        log.debug(
            "PooledDataSource: Unknown severe error condition.  The connection pool returned a null connection.");
      }
      throw new SQLException(
          "PooledDataSource: Unknown severe error condition.  The connection pool returned a null connection.");
    }

    return conn;
  }
コード例 #14
0
 public Connection getConnection() throws SQLException {
   return popConnection(dataSource.getUsername(), dataSource.getPassword()).getProxyConnection();
 }
コード例 #15
0
 public void setDefaultAutoCommit(boolean defaultAutoCommit) {
   dataSource.setAutoCommit(defaultAutoCommit);
   forceCloseAll();
 }
コード例 #16
0
 public void setPassword(String password) {
   dataSource.setPassword(password);
   forceCloseAll();
 }
コード例 #17
0
 public void setUsername(String username) {
   dataSource.setUsername(username);
   forceCloseAll();
 }
コード例 #18
0
 public void setUrl(String url) {
   dataSource.setUrl(url);
   forceCloseAll();
 }
コード例 #19
0
 public void setDriver(String driver) {
   dataSource.setDriver(driver);
   forceCloseAll();
 }
コード例 #20
0
 public PooledDataSource(String driver, String url, String username, String password) {
   dataSource = new UnpooledDataSource(driver, url, username, password);
   expectedConnectionTypeCode =
       assembleConnectionTypeCode(
           dataSource.getUrl(), dataSource.getUsername(), dataSource.getPassword());
 }
コード例 #21
0
 public void setDriverProperties(Properties driverProps) {
   dataSource.setDriverProperties(driverProps);
   forceCloseAll();
 }
コード例 #22
0
 @Override
 public Connection getConnection()
     throws SQLException { // 获得连接,即popConnection(...).getProxyConnection()获得代理连接
   return popConnection(dataSource.getUsername(), dataSource.getPassword()).getProxyConnection();
 }
コード例 #23
0
 public String getDriver() {
   return dataSource.getDriver();
 }