Vertx JDBC如何在引擎盖下工作

时间:2018-05-20 06:07:09

标签: java asynchronous jdbc vert.x

我一直在使用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语句从DB返回结果时,它将被执行,但它是如何工作的。

我在文档https://vertx.io/docs/vertx-jdbc-client/java/

中找不到答案

在我看来:

Vertx使用其中一个工作线程来执行select语句而不阻塞事件循环线程。但在这种情况下,每个sql查询都需要一个单独的线程来执行。 但是如果Vertx不使用任何单独的线程来执行查询,在这种情况下事件循环如何知道结果来自DB,使用线程非常简单,事件循环可以检查jdbc查询使用的线程的当前状态,以及如果状态已准备就绪,则意味着Event循环应执行回调

我是对的吗?

2 个答案:

答案 0 :(得分:7)

一般来说,你是对的 你可以自己看一下:

方法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

执行

答案 1 :(得分:1)

Vertx JDBC的非阻塞如何工作?要知道这个答案,你需要深入研究vertx doc和非阻塞理论。

让我们谈谈您的代码。

  

的Connection.close();

这行代码不是必需的。 Vertx将根据他们的文档处理它。

使用JDBC执行查询时使用vertx,我们可以执行以下两项操作:

  1. 打开连接,按顺序执行多个查询,最后关闭连接,即阻止代码
  2. 打开连接,执行单个查询然后关闭连接,如果我们没有认真关注连接,这是令人头痛的编码方式。
  3. 现在让我们分析一下非阻塞Vertx JDBC的工作原理。 如果我们看到更多关闭点2,即打开连接,执行单个查询然后关闭连接。如果我们并行完成并且负责关闭已经由vertx处理的连接,那么我们已经实现了不完全但非阻塞的查询执行