[java] 非同期jdbc呼び出しは可能ですか?


Answers

JDBCを介してデータベースへの非同期呼び出しを行うことは不可能ですが、 Actors を使用してJDBCに非同期呼び出し行うこともできます (たとえば、アクターがJDBC経由でDBに呼び出しを行い、呼び出しが終了したときにサードパーティにメッセージを送信します)。 CPSが好きであれば、 パイプラインの先物(約束) (良い実装はScalaz Promises

スレッドのプールを使用することは解決策ではないと考えています。大規模な同時リクエストの場合、非常に多数のスレッドが生成されます。

Scalaのアクタは、デフォルトではイベントベース(スレッドベースではありません)です。継続スケジューリングでは、標準のJVMセットアップで数百万のアクタを作成できます。

Javaをターゲットにしている場合、 Akka FrameworkはJavaとScalaの両方に優れたAPIを持つActorモデルの実装です。

それとは別に、JDBCの同期的な性質は私にとって完璧な意味を持ちます。 データベースセッションのコストは、Javaスレッドが(前面またはバックグラウンドで)ブロックされ、応答を待っているコストよりもはるかに高いです。 あなたのクエリが実行時間が長くなりすぎてexecutorサービス(またはActor / fork-join / promise並行処理フレームワークをラッピングする)の能力が十分ではない(そしてスレッドが多すぎる)場合、まずあなたのことを考える必要がありますデータベースの負荷。 通常、データベースからの応答は非常に高速になり、固定スレッド・プールでバックアップされたExecutorサービスは十分な解決策です。 長期実行クエリが多すぎる場合は、夜間にデータを再計算するなどの前処理(前処理)を考慮する必要があります。

Question

データベースへの非同期呼び出しを行う方法があるのだろうか?

たとえば、処理に時間がかかるという大きな要求があると想像してください。リクエストを送信し、リクエストが値を返すときにリスナー/コールバックなどを渡して通知を受け取る必要があります。 私はデータベースが答えるのを待つのをブロックしたくありません。

スレッドのプールを使用することは解決策ではないと考えています。大規模な同時リクエストの場合、非常に多数のスレッドが生成されます。

私たちはこのようなネットワークサーバーの問題に直面しており、select / poll / epollシステムコールを使用して接続ごとに1つのスレッドが存在しないようにするソリューションを見つけました。 私はちょうどデータベースの要求と同様の機能を持っているのだろうか?

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

**アップデート**
本当の実用的なソリューションがないので、私は自分自身でライブラリ(finagleの一部)を作成することにしました: finagle-mysql 。 基本的には、mysqlのリクエスト/レスポンスをデコード/デコードし、フードの下でFinagle / Nettyを使用します。 膨大な数の接続でも非常にうまく拡張できます。




Ajdbcプロジェクトはこの問題に対処しているようですhttp://code.google.com/p/adbcj/

現在のところ、mysqlとpostgresqlの2つの実験的に非同期のドライバがあります。




ちょっと狂ったアイデア:JBDCのresultSetにIterateeパターンを使ってFuture /

HammersmithはMongoDBのためにそれを行います。




JDBCには直接サポートはありませんが、MDB、Java 5のExecutorsなどの複数のオプションがあります。

「スレッドのプールを使用することは、規模が大きくないため解決策ではないと考えています。同時要求が多いと、非常に多くのスレッドが生成されます」

なぜスレッドの束縛されたプールが拡大縮小しないのでしょうか? これは、要求ごとにスレッドを生成する要求ごとのスレッドではないプールです。 私は重い負荷のWebアプリケーションでこれをいつか使っていますが、これまでに何の問題も見ていません。




commons-dbutilsライブラリは、 ExecutorServiceを提供するAsyncQueryRunnerをサポートし、 Future返します。 チェックするだけで簡単に使用でき、リソースが漏れないようにすることができます。










Links