在Vert.x中使用SQL - Alexey Soshin

banq發表於2019-07-13

Vert.x是非同步的。在Vert.x中執行資料庫查詢時,您顯然正在傳遞迴調。那麼,它是非同步的?:

conn.updateWithParams("insert into user (email, name, password) values (?, ?, ?)", params,
  (r) -> {
        if (r.succeeded()) {
            System.out.println("Ok!");
        }
        else {
            if (r.cause() instanceof MySQLException) {
                MySQLException cause = (MySQLException) r.cause();
                if (cause.errorMessage().errorCode() == 1062) {
                    // Duplicate key, ignore
                }
            }


不完全對,看看queryWithParams 方法內部:

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


JDBCQuery 是一個簡單物件,有趣部分是execute()方法,進入AbstractJDBCAction看看這個方法:

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


注意到呼叫的executeBlocking方法名稱,你可能疑惑ctx來自哪裡,其實來自JDBCClientImpl:

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


結論是,最後,常規的Vert.x JDBC客戶端沒有任何魔力。它使用了一個簡單的資料來源:預設情況下為C3P0,但如果您願意,也可以使用Hikari。您可能希望將池大小設定得更大,預設為15個連線
這種實現的主要目標很簡單 - 不阻止事件迴圈(從不阻止事件迴圈)。對大多數用例來說,它實際上非常好。只是不要指望它會用JDBC做一些神奇的事情,就像讓它無阻塞一樣。
 

相關文章