美文网首页HiKariCP
HiKariCP源码-获取连接

HiKariCP源码-获取连接

作者: Young_5942 | 来源:发表于2019-12-23 21:17 被阅读0次
    HikariDataSource类图

    获取连接时序图


    获取连接时序图

    初始化代码

    HikariDataSource ds = new HikariDataSource();
          ds.setJdbcUrl("jdbc:mysql://localhost:3306/test");
          ds.setUsername("xx");
          ds.setPassword("xxx");
          ...
    

    getConnection()

    @Override
       public Connection getConnection() throws SQLException
       {
          if (isClosed()) {
             throw new SQLException("HikariDataSource " + this + " has been closed.");
          }
    
          if (fastPathPool != null) {
             return fastPathPool.getConnection();
          }
    
          // See http://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java
          HikariPool result = pool;
          if (result == null) {
             synchronized (this) {
                result = pool;
                if (result == null) {
                   validate();
                   LOGGER.info("{} - Starting...", getPoolName());
                   try {
                      pool = result = new HikariPool(this);
                      this.seal();
                   }
                   catch (PoolInitializationException pie) {
                      if (pie.getCause() instanceof SQLException) {
                         throw (SQLException) pie.getCause();
                      }
                      else {
                         throw pie;
                      }
                   }
                   LOGGER.info("{} - Start completed.", getPoolName());
                }
             }
          }
    
          return result.getConnection();
       }
    

    HikariPool 使用双重检查加锁初始化
    具体的获取连接在HikarPool实现

     public Connection getConnection() throws SQLException
       {
          return getConnection(connectionTimeout);
       }
    
    public Connection getConnection(final long hardTimeout) throws SQLException
       {
          suspendResumeLock.acquire();
          final long startTime = currentTime();
    
          try {
             long timeout = hardTimeout;
             do {
                PoolEntry poolEntry = connectionBag.borrow(timeout, MILLISECONDS);
                if (poolEntry == null) {
                   break; // We timed out... break and throw exception
                }
    
                final long now = currentTime();
                if (poolEntry.isMarkedEvicted() || (elapsedMillis(poolEntry.lastAccessed, now) > aliveBypassWindowMs && !isConnectionAlive(poolEntry.connection))) {
                   closeConnection(poolEntry, poolEntry.isMarkedEvicted() ? EVICTED_CONNECTION_MESSAGE : DEAD_CONNECTION_MESSAGE);
                   timeout = hardTimeout - elapsedMillis(startTime);
                }
                else {
                   metricsTracker.recordBorrowStats(poolEntry, startTime);
                   return poolEntry.createProxyConnection(leakTaskFactory.schedule(poolEntry), now);
                }
             } while (timeout > 0L);
    
             metricsTracker.recordBorrowTimeoutStats(startTime);
             throw createTimeoutException(startTime);
          }
          catch (InterruptedException e) {
             Thread.currentThread().interrupt();
             throw new SQLException(poolName + " - Interrupted during connection acquisition", e);
          }
          finally {
             suspendResumeLock.release();
          }
       }
    

    connectionTimeout 获取连接的最大等待时间
    从connectionBag借用连接,判断连接的有效性 如果无效连接则关闭连接
    如果连接有效,通过ProxyFactory创建物理连接和poolEntry对应
    poolEntry.createProxyConnection(leakTaskFactory.schedule(poolEntry), now);实现:

    Connection createProxyConnection(final ProxyLeakTask leakTask, final long now)
       {
          return ProxyFactory.getProxyConnection(this, connection, openStatements, leakTask, now, isReadOnly, isAutoCommit);
       }
    
    static ProxyConnection getProxyConnection(final PoolEntry poolEntry, 
    final Connection connection, 
    final FastList<Statement> openStatements, 
    final ProxyLeakTask leakTask, 
    final long now,
     final boolean isReadOnly,
     final boolean isAutoCommit)
       {
          // Body is replaced (injected) by JavassistProxyFactory
          throw new IllegalStateException("You need to run the CLI build and you need target/classes in your classpath to run.");
       }
    
    UML时序图.png

    相关文章

      网友评论

        本文标题:HiKariCP源码-获取连接

        本文链接:https://www.haomeiwen.com/subject/igkunctx.html