Vertx JDBC 它是如何工作的
Vertx JDBC how it works under the hood
我已经使用 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 语句将 return 来自 DB 的结果时执行,但它是如何工作的。
我没有在文档中找到答案https://vertx.io/docs/vertx-jdbc-client/java/
我认为:
Vertx 使用其中一个工作线程来执行 select 语句以不阻塞事件循环 thread.But 在这种情况下每个 sql 查询都需要一个单独的线程来执行。
但是如果 Vertx 不使用任何单独的线程来执行查询,在这种情况下事件循环如何知道结果何时来自数据库,使用线程非常简单,事件循环可以检查 [=27= 使用的线程的当前状态]查询,如果状态准备就绪,则意味着事件循环应该执行回调
我说的对吗?
非阻塞 Vertx JDBC 是如何工作的?要知道这个答案,您需要深入了解 vertx 文档和非阻塞理论。
让我们谈谈您的代码。
connection.close();
这行代码不是必需的。 Vertx 将根据他们的文档处理它。
当我们使用 JDBC 执行查询时,使用 vertx,我们可以做以下两件事:
- 打开连接,依次执行多个查询,最后关闭连接,这是阻塞代码
- 打开连接,执行单个查询,然后关闭连接,如果我们不认真关闭连接,这是一种令人头疼的编码方式。
现在让我们分析一下非阻塞 Vertx JDBC 是如何工作的。
如果我们更多地关注点 2,即 打开连接,执行单个查询然后关闭连接 。如果我们并行执行并认真处理 vertx 已经处理的关闭连接,那么我们已经实现了不完全但近似的非阻塞查询执行
总的来说,你是对的。
你可以自己看看幕后花絮:
方法 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
执行
我已经使用 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 语句将 return 来自 DB 的结果时执行,但它是如何工作的。
我没有在文档中找到答案https://vertx.io/docs/vertx-jdbc-client/java/
我认为:
Vertx 使用其中一个工作线程来执行 select 语句以不阻塞事件循环 thread.But 在这种情况下每个 sql 查询都需要一个单独的线程来执行。 但是如果 Vertx 不使用任何单独的线程来执行查询,在这种情况下事件循环如何知道结果何时来自数据库,使用线程非常简单,事件循环可以检查 [=27= 使用的线程的当前状态]查询,如果状态准备就绪,则意味着事件循环应该执行回调
我说的对吗?
非阻塞 Vertx JDBC 是如何工作的?要知道这个答案,您需要深入了解 vertx 文档和非阻塞理论。
让我们谈谈您的代码。
connection.close();
这行代码不是必需的。 Vertx 将根据他们的文档处理它。
当我们使用 JDBC 执行查询时,使用 vertx,我们可以做以下两件事:
- 打开连接,依次执行多个查询,最后关闭连接,这是阻塞代码
- 打开连接,执行单个查询,然后关闭连接,如果我们不认真关闭连接,这是一种令人头疼的编码方式。
现在让我们分析一下非阻塞 Vertx JDBC 是如何工作的。 如果我们更多地关注点 2,即 打开连接,执行单个查询然后关闭连接 。如果我们并行执行并认真处理 vertx 已经处理的关闭连接,那么我们已经实现了不完全但近似的非阻塞查询执行
总的来说,你是对的。
你可以自己看看幕后花絮:
方法 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