1. ホーム
  2. java

[解決済み] 非同期jdbcコールは可能ですか?

2022-04-22 22:43:42

質問

データベースを非同期で呼び出す方法はないのでしょうか?

例えば、処理に非常に時間がかかる大きなリクエストがあったとして、リクエストを送信し、リクエストが値を返したときに通知を受け取りたいとします(リスナー/コールバックか何かを渡すことによって)。私はデータベースが答えるのを待つためにブロックしたくありません。

スレッドのプールを使用することは、スケールしないため、解決策とは考えていません。重い同時リクエストの場合、非常に多くのスレッドを生成することになります。

私たちはネットワークサーバーでこの種の問題に直面しており、接続ごとに1つのスレッドを持つことを避けるためにselect/poll/epollシステムコールを使用することで解決策を見出しています。データベース・リクエストで同様の機能を持つにはどうすればよいのでしょうか?

注 FixedThreadPoolを使用することが良い回避策であることは承知していますが、誰も本当に非同期な(余分なスレッドを使用しない)システムを開発していないことに驚いています。

** アップデート

実際に実用的なソリューションがないため、自分でライブラリ(finagleの一部)を作成することにしました。 finagle-mysql . 基本的にはmysqlのリクエスト/レスポンスをデコードし、Finagle/Nettyを使用します。膨大な数のコネクションがあっても、非常にうまくスケールします。

解決方法は?

JDBCコールをアクターやエグゼキューターなどでラップする提案されたアプローチのどれが、ここでどのように役立つのか理解できません。

基本的な問題は、JDBC操作がソケットIOでブロックされることでしょう。これを実行すると、実行中のスレッドがブロックされます - 話は終わりです。どのようなラッピングフレームワークを使用するにしても、同時リクエストごとに1つのスレッドがビジー状態またはブロックされた状態で終了することになります。

もし、基礎となるデータベースドライバ(MySql?)がソケット作成を傍受する手段(SocketFactory参照)を提供するなら、JDBC apiの上に非同期イベント駆動データベース層を構築することは可能でしょうが、JDBC全体をイベント駆動ファサードの後ろにカプセル化しなければならず、そのファサードはJDBCとは見えません(イベント駆動となる後)。 データベース処理は呼び出し元とは別のスレッドで非同期に行われ、スレッドアフィニティに依存しないトランザクションマネージャを構築する方法を考えなければならないでしょう。

私が言及したアプローチのようなものは、単一のバックグラウンドスレッドでさえ、同時実行JDBCの負荷を処理することを可能にします。実際には、マルチコアを使用するためにスレッドのプールを実行することになるでしょう。

(もちろん、私は元の質問の論理についてコメントしているのではなく、セレクタパターンを使用しなくても、ブロッキングソケットIOのシナリオで並行処理が可能であることをほのめかす回答についてです - 通常のJDBC並行処理と適切なサイズの接続プールを置くだけなので、よりシンプルです)。


MySql はおそらく私が提案するようなことを行っているようです ---。 http://code.google.com/p/async-mysql-connector/wiki/UsageExample