HiKariCP

HiKariCP源码-获取连接

2019-12-23  本文已影响0人  Young_5942
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
上一篇下一篇

猜你喜欢

热点阅读