4

我可能误解了 Play Framework (2.x) 的一些基本内容,但是关于访问普通 SQL 数据库的文档和这样做的项目示例似乎都没有异步执行此操作。

没有Promise<Result>,没有 Akka 的东西等。

如果您使用普通的 MySQL JDBC 驱动程序进行数据库查询,您是否不会阻塞主服务器线程?我错过了什么?

4

2 回答 2

3

是的,db 驱动程序阻塞了等待数据库结果的线程。

即使您像 ico_ekito 建议的那样将 JDBC 调用包装在 Akka 未来中,它仍然会在整个数据库请求期间阻塞一个服务器线程。这样做可能只会在不同的线程上执行调用(取决于 Akka 决定如何执行它),但它仍然会阻塞该线程。

解决此问题的唯一正确方法是使用非阻塞数据库驱动程序。

顺便说一句,您可以很容易地发现阻塞的数据库驱动程序。如果它的界面看起来像这样:

ResultSet results = connection.execute(query);

它肯定是阻塞的。您可以通过返回 Futures、Promises(具有写入端的 Futures)或接受回调的方法来识别非阻塞 API。

另请注意,没有“主”服务器线程(如浏览器/桌面应用程序中的 UI 线程)。只有几个线程处理请求。

如需更深入的讨论,请查看此处

于 2012-11-30T17:26:07.780 回答
3

AFAIK,如果您正在查看“计算机数据库”示例,那么您是完全正确的,它阻塞了主线程,因为操作不是异步执行的。

这是样本的摘录:

public static Result list(int page, String sortBy, String order, String filter) {
    return ok(
        list.render(
            Computer.page(page, 10, sortBy, order, filter),
            sortBy, order, filter
        )
    );
}

在这里,Computer.page()正在执行一些 JDBC 阻塞调用。

如果您想异步执行此操作,则应将数据库调用包含在async(F.Promise<Result>)调用中。像这样的东西:

public static Result list(int page, String sortBy, String order, String filter) {
    return async(
            Akka.future(
                new Callable<Result>() {
                  public Result call() {
                    return ok(
                        list.render(
                            Computer.page(page, 10, sortBy, order, filter),
                            sortBy, order, filter
                        )
                    );
                  }
                }
        )
    );

}

于 2012-11-29T08:58:55.907 回答