如何在Play Java中创建数据库线程池并使用此池进行数据库查询
我目前正在使用play java并使用默认线程池进行数据库查询,但了解使用数据库线程池进行数据库查询可以使我的系统更高效.目前我的代码是
I am currently using play java and making db queries also with default threadpool but understand that doing db queries with db thread pool can make my system more efficient. Currently my code is
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
我正在尝试以以下方式创建线程池
I am trying to create threadpool in the following manner
ExecutionContext myExecutionContext = Akka.system().dispatchers().lookup("play.akka.actor.my-context");
我是否以正确的方式创建了线程池,如果是的话,如何使用该线程池将代码更改为以下内容
Am I creating threadpool in the right manner and if yes how do I use this threadpool to change my code to following
SqlQuery query = Ebean.createSqlQuery(sqlQuery);
CompletionStage<List<SqlRow>> = //query.findList(myExecutionContext)
// do some computation over the data obtained and send as response
我正在尝试以正确的方式做到这一点?
I am trying to do it in the right way?
注意;如果我使用
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
如何设置最大线程数之类的设置?我想使用此池使用可用的阻塞驱动程序来调用oracle db.因此,我要在此池中使用的最大线程数等于我可以与数据库建立的数据库连接数.
how do I set the settings like the max threads? I would like to use this pool to make calls to oracle db using blocking driver available. So max threads I want in this pool is equal to number of db connections I can make to my database.
First of all, you should take a look at the ThreadPoll Configuration docs, if you haven't done that yet. It should give you an overview of the thread pools Play uses by default and how to tweak them (you may not need a specific thread pool just to do queries...).
它包含许多技巧,包括配置针对JDBC操作优化的线程池的技巧.
It contains a lot of tips, including tips to configure thread pools optimized to JDBC operations.
现在,关于您的问题,您只需将supplyAsync
与自定义ExecutorService
结合使用即可完成所需的工作.一个例子:
Now, regarding your question, you just have to use supplyAsync
with a custom ExecutorService
to do what you need. An example:
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
并共享它
Notice that from your code, you are using Akka to get an ExecutionContext
(Scala), and the supplyAsync
expects an Executor/ExecutorService
(Java). So you will have to create your ServiceExecutor
by yourself and share it
// Thread pool with 10 threads
ExecutorService ec = Executors.newFixedThreadPool(10);
,否则您将不得不在它们之间进行转换. 此要点应该可以帮助您实现这一目标
or you will have to convert between them. This gist should help you achieve that