code: @Override
    public Connection getConnection() throws SQLException {
  
      this.dbMetrics.markDBConnection();
      final long startMs = System.currentTimeMillis();
      Connection connection = null;
      int retryAttempt = 1;
      while (retryAttempt < AzDBUtil.MAX_DB_RETRY_COUNT) {
        try {
          /**
           * when DB connection could not be fetched (e.g., network issue), or connection can not be validated,
           * {@link BasicDataSource} throws a SQL Exception. {@link BasicDataSource#dataSource} will be reset to null.
           * createDataSource() will create a new dataSource.
           * Every Attempt generates a thread-hanging-time, about 75 seconds, which is hard coded, and can not be changed.
           */
          connection = createDataSource().getConnection();
  
          /**
           * If connection is null or connection is read only, retry to find available connection.
           * When DB fails over from master to slave, master is set to read-only mode. We must keep
           * finding correct data source and sql connection.
           */
          if (connection == null || isReadOnly(connection)) {
            throw new SQLException("Failed to find DB connection Or connection is read only. ");
          } else {
  
            // Evalaute how long it takes to get DB Connection.
            this.dbMetrics.setDBConnectionTime(System.currentTimeMillis() - startMs);
            return connection;
          }
        } catch (final SQLException ex) {
  
          /**
           * invalidate connection and reconstruct it later. if remote IP address is not reachable,
           * it will get hang for a while and throw exception.
           */
          this.dbMetrics.markDBFailConnection();
          try {
            invalidateConnection(connection);
          } catch (final Exception e) {
            logger.error( "can not invalidate connection.", e);
          }
          logger.error( "Failed to find write-enabled DB connection. Wait 15 seconds and retry."
              + " No.Attempt = " + retryAttempt, ex);
          /**
           * When database is completed down, DB connection fails to be fetched immediately. So we need
           * to sleep 15 seconds for retry.
           */
          sleep(1000L * 15);
          retryAttempt++;
        }
      }
      return connection;
    }
docs: This method overrides {@link BasicDataSource#getConnection()}, in order to have retry logics.
  We don't make the call synchronized in order to guarantee normal cases performance.