@AlexFox2019
Junior Java Developer

Корректно ли использовать таким образом CompletableFuture и JdbcTemplate?

Всем привет. Есть задача: сделать один вызов в одну базу данных и другой вызов в другую базу данных. Над результатами сделать определенные действия.
Текущая реализация моя следующая:
Dao1 делает select запрос1.
Dao2 делает select запрос2.
Делаем обработку результатов двух запросов.

Хотелось бы запрос1 и запрос2 делать одновременно. Реализовал так:

@Async
public CompletableFuture<Response1> query1(){
    return CompletableFuture.completedFuture(jdbcTemplate1.query(sql, , ))
}
@Async
public CompletableFuture<Response2> query2(){
    return CompletableFuture.completedFuture(jdbcTemplate2.query(sql, , ))
}


Далее в коде:

CompletableFuture<Response1> response1Future = query1();
 CompletableFuture<Response2> response2Future = query2();

 CompletableFuture.allOf(response1Future, response2Future).join();
//

Насколько такой подход хорош или плохой? Хотелось бы узнать мнения опытных людей.!
Спасибо.!
  • Вопрос задан
  • 324 просмотра
Решения вопроса 1
CellycoMobiles
@CellycoMobiles
indi developer @CellycoMobiles
  1. Избавляемся от конкретизации интерфейса CompletionStage. Тру реакционщики пишут свои интерпретации.
  2. Абстрагируемся от возвращаемого значения посредством интерфейса или абстрактного классаю Например DBResponse. Завтра вам надоест мускул, уйдете в носкул. Достаточно будет интерфейс переписать.
  3. Унифицируем получение данных, вынося в сигнатуру метода однотипные переменные. queryAsync Завтра смените DSL на jooq - достаточно будет только один метод переписать.
  4. Постарайтесь избавиться от JOIN. Очень дорогой метод, грубо приводящий реактивное программирование к императивному. Используйте thenAcceptAsync, exceptionallyAsync, handleAsync Метод result()


public CompletionStage<DBResponse> query1(){
        return queryAsync(jdbc, sql, param1, param2, ... paramN);
    }

    public CompletionStage<DBResponse> query2(){
        return queryAsync(jdbc, sql, param2, param3, ... paramN);
    }

    public CompletionStage<DBResponse> queryAsync(JDBC jdbc, sql, Objects ... params){
        return CompletableFuture.supplyAsync(() -> {
            return jdbc.query(sql, params);
        }).thenApplyAsync(DBResponse::of);
    }

//    далее в коде

    void result(){
        CompletableFuture.allOf(query1(), query2())
                .thenAcceptAsync( ... );
    }

    public static interface DBResponse {
        default DBResponse of(Response resp){
            ...;
        }
    }


P.S. Ничего не написал про concurency, не знаю, как вы используете. Имхо удобно инстанцировать отдельный пул на каждый тип операций (disk, http, sql, ui, ...).
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы