Vertx JDBC, как это работает под капотом - PullRequest
0 голосов
/ 20 мая 2018

Я использую Vertx в течение 3 месяцев, но теперь мне интересно, как работает неблокирующая Vertx JDBC, например

private void selectEndedMatches(){
        this.jdbcClient.getConnection(conn->{
            if(conn.failed()){
                log.error("Can't get Vertx connection",conn.cause());
            } else{
                final SQLConnection connection = conn.result();
                connection.queryWithParams("select matchid from get5_stats_matches where matchid > ? and end_time is not null",new JsonArray().add(this.lastMatchId),this::endedMatches);
                connection.close();
            }
        });
    }


private void endedMatches(final AsyncResult<ResultSet> rs) {
        if(rs.failed()){
            log.error("Can't make select statement from JdbcVerticle",rs.cause());
        } else{
            final List<JsonArray> results = rs.result().getResults();
            final List<Integer> endedMatches = new ArrayList<>(results.size());
            for (final JsonArray result : results) {
                endedMatches.add(result.getInteger(0));
            }

        }
    }

Здесь мы предоставляем обратный вызов, который будет выполнен, когда наш оператор select вернетрезультат из БД, но как он работает.

Я не нашел ответа в документах https://vertx.io/docs/vertx-jdbc-client/java/

По моему мнению:

Vertx использует один из рабочих потоковсделать оператор select, чтобы не блокировать поток цикла Event.But. Но в этом случае для каждого SQL-запроса требуется отдельный поток для выполнения.Но что, если Vertx не использует какой-либо отдельный поток для выполнения запроса, в этом случае, как цикл обработки событий узнает, когда результат поступил из БД, используя потоки, это довольно просто, цикл обработки событий может проверить текущее состояние потока, который используется запросом jdbc, иесли состояние готово, это означает, что цикл обработки событий должен выполнить обратный вызов

Правильно ли я?

Ответы [ 2 ]

0 голосов
/ 20 мая 2018

В общем, вы правы.
Вы можете увидеть под капотом себя:

Метод queryWithParams() Звонки execute():

public SQLConnection queryWithParams(String sql, JsonArray params, Handler<AsyncResult<ResultSet>> resultHandler) {
    new JDBCQuery(vertx, helper, options, ctx, sql, params).execute(conn, statementsQueue, resultHandler);
    return this;
  }

И execute() выглядит так:

public void execute(Connection conn, TaskQueue statementsQueue, Handler<AsyncResult<T>> resultHandler) {
    ctx.executeBlocking(future -> handle(conn, future), statementsQueue, resultHandler);
}

Вы можете задаться вопросом, откуда взялся ctx.Это в JDBCClientImpl:

public SQLClient getConnection(Handler<AsyncResult<SQLConnection>> handler) {
    Context ctx = vertx.getOrCreateContext();
    getConnection(ctx, ar -> ctx.runOnContext(v -> handler.handle(ar)));
    return this;
  }

И ваш запрос выполняется простым старым ExecutorService

0 голосов
/ 20 мая 2018

как работает неблокирующий Vertx JDBC?Чтобы знать этот ответ, вам нужно углубиться в документ vertx и теорию неблокирования.

Давайте поговорим о вашем коде.

connection.close ();

Эта строка кода не требуется.Vertx позаботится об этом согласно их документации.

С помощью vertx, когда мы выполняем запрос с использованием JDBC, мы можем сделать следующие две вещи:

  1. Открыть соединение, Выполнить несколько запросов последовательно инаконец, закрыть соединение, которое блокирует код
  2. Открыть соединение, выполнить один запрос и затем закрыть соединение, что является головной болью, если мы не позаботились о закрытии соединения всерьез.

Теперь давайте проанализируем, как работает неблокирующая Vertx JDBC.Если мы посмотрим больше закрытия на пункт 2, то есть Открыть соединение, выполнить один запрос и затем закрыть соединение .Если мы сделаем это параллельно и серьезно позаботимся о закрытии соединения, которое уже решено с помощью vertx, то мы добились не точного, но приблизительного неблокирующего выполнения запроса

...