admin

如何在Play Java中创建数据库线程池并使用此池进行数据库查询

sql

我目前正在使用play java并使用默认线程池进行数据库查询,但了解使用数据库线程池进行数据库查询可以使我的系统更高效。目前我的代码是

import play.libs.Akka;
import scala.concurrent.ExecutionContext;

String sqlQuery = "very long query with lot of joins"
SqlQuery query = Ebean.createSqlQuery(sqlQuery);
List<SqlRow> rows = query.findList();
// do some computation over the data obtained and send as response

我正在尝试以以下方式创建线程池

ExecutionContext myExecutionContext = Akka.system().dispatchers().lookup("play.akka.actor.my-context");

我是否以正确的方式创建线程池,如果是,我如何使用该线程池将代码更改为以下内容

SqlQuery query = Ebean.createSqlQuery(sqlQuery);
CompletionStage<List<SqlRow>> = //query.findList(myExecutionContext)
// do some computation over the data obtained and send as response

我正在尝试以正确的方式做到这一点?

笔记; 如果我使用存在的Java执行器

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

如何设置最大线程数之类的设置?我想使用此池使用可用的阻塞驱动程序来调用oracle
db。因此,我要在此池中使用的最大线程数等于我可以与数据库建立的数据库连接数。


阅读 138

收藏
2021-06-07

共1个答案

admin

首先,如果尚未完成操作,则应查看ThreadPoll配置文档。它应该为您提供Play默认使用的线程池以及如何对其进行调整的概述(您可能不需要特定的线程池来执行查询…)。

它包含许多技巧,包括配置针对JDBC操作优化的线程池的技巧。

现在,关于您的问题,您只需要使用supplyAsync自定义ExecutorService即可完成所需的工作。一个例子:

public CompletionStage<Result> getData() {
    CompletableFuture<List<SqlRow>> cf = new CompletableFuture<>();
    return cf.supplyAsync(() -> {
        return Ebean.createSqlQuery("SELECT * FROM Users").findList();
    }, ec) // <-- 'ec' is the ExecutorService you want to use
    .thenApply(rows -> {
       return ok(Json.toJson(rows));
    }); 
}

请注意,从您的代码中,您正在使用Akka来获取ExecutionContext(Scala),并且supplyAsync期望使用Executor/ExecutorService(Java)。因此,您将必须自己创建ServiceExecutor并共享

// Thread pool with 10 threads
ExecutorService ec = Executors.newFixedThreadPool(10);

否则您将不得不在它们之间进行转换。要点应该可以帮助您实现

2021-06-07