public synchronized PreparedStatement getPreparedStatement(String sql, boolean needWritable) throws SQLException {
    // If connected to suboptimal endpoint, attempt to upgrade every so often
    long now = System.currentTimeMillis();
    if (lastConnectionAttemptTime < now - connectionRetryWaitTime) {
      getDatabaseConnection(needWritable);
      lastConnectionAttemptTime = now;
    }
    PreparedStatement statement = statementCache.get(sql);
    if (statement != null && !statement.isClosed()) {
      return statement;
    }
    Connection connection = getDatabaseConnection(needWritable);
    statement = connection.prepareStatement(sql);
    statementCache.put(sql, statement);
    return statement;
  }
@return a {@link PreparedStatement} using the supplied SQL text.
@param sql the SQL text to use.
@throws SQLException
ambry-mysql/src/main/java/com/github/ambry/mysql/MySqlDataAccessor.java