4

私はおそらくPlayFramework(2.x)の基本的なことを誤解していますが、通常のSQLデータベースへのアクセスに関するドキュメントとプロジェクトサンプルの両方がこれを非同期的に行っているようには見えません。

Promise<Result>Akkaのものなどはありません。

たとえば、通常のMySQL JDBCドライバーを使用してデータベースクエリを実行する場合、メインサーバースレッドをブロックしていませんか?私は何が欠けていますか?

4

2 に答える 2

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 に答える
3

はい、dbドライバーは、データベースからの結果を待機しているスレッドをブロックします。

ico_ekitoが提案するようにAkkaの将来でJDBC呼び出しをラップした場合でも、データベース要求の全期間中、1つのサーバースレッドをブロックします。これを行うと、別のスレッドでのみ呼び出しが実行される可能性があります(Akkaが実行を決定する方法によって異なります)が、それでもそのスレッドはブロックされます。

これを回避する唯一の適切な方法は、ノンブロッキングデータベースドライバーを使用することです。

ところで、ブロッキングデータベースドライバを非常に簡単に見つけることができます。そのインターフェースが次のようになっている場合:

ResultSet results = connection.execute(query);

間違いなくブロックしています。ノンブロッキングAPIは、Futures、Promises(書き込み側のFutures)を返すメソッド、またはコールバックを取得するメソッドによって認識できます。

また、「メイン」サーバースレッド(ブラウザ/デスクトップアプリケーションのUIスレッドなど)がないことにも注意してください。リクエストを処理するスレッドはいくつかあります。

詳細については、こちらをご覧ください。

于 2012-11-30T17:26:07.780 に答える