Vertx JDBC how it works under the hood

2019-07-14 06:12发布

问题:

I have been using Vertx for 3 month, but now I wonder how non blocking Vertx JDBC works,for example

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));
            }

        }
    }

Here we provide a callback that will be executed when our select statement will return a result from DB, but how it works.

I didn't find an answer in docs https://vertx.io/docs/vertx-jdbc-client/java/

In my opinion:

Vertx use one of the worker threads to do select statement to not block Event loop thread.But in this case each sql query need a separate thread to execute. But what if Vertx doesn't use any separate thread to execute query, in this case how event loop know when result came from DB, using threads it's pretty simple, Event loop can check current state of thread that is used by jdbc query, and if state is ready it's mean that Event loop should to execute Call back

Am i correct?

回答1:

In general, you're correct.
You can see under the hood yourself:

Method queryWithParams() calls 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;
  }

And execute() looks like this:

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

You may wonder where does ctx comes from. It's in JDBCClientImpl:

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

And your query is executed by plain old ExecutorService



回答2:

how nonblocking Vertx JDBC works? To Know this answer you need to go depth of the vertx doc and theory of non blocking.

Let's talk with respect to your code.

connection.close();

This line of code is not required. Vertx will take care of it as per their documentation.

With vertx when we execute query using JDBC,We can do following two things:

  1. Open connection, Execute multiple queries sequentially and the finally close the connection, which is blocking code
  2. Open connection, execute single query and then close the connection,which is headache way of coding if we didn't take care closing connection seriously.

Now let's analyze the how nonblocking Vertx JDBC works. If we look more closure to point 2,i.e Open connection, execute single query and then close the connection . If we do it in parallel and take care of closing connection seriously which already take care by vertx ,then we have achieved the not exactly but approx non-blocking query execution