1

あるソースから常にデータを抽出してデータベースに書き込むプログラムに、c3p0でhibernate3を使用しています。ここで問題となるのは、何らかの理由でデータベースが使用できなくなる可能性があることです(最も単純なケースでは、単にデータベースをシャットダウンします)。

データベースに何かが書き込まれようとしている場合でも、例外はありません。クエリは、データベースが再び使用可能になるまで、永遠に待機する必要があります。私が間違っていない場合、これは接続プールが私のためにできることの1つです。データベースに問題がある場合は、接続を再試行してください。最悪の場合、無限大です。

しかし、代わりに、壊れたパイプの例外が発生し、接続が拒否された後、例外が自分のコードに渡されることがありますが、これは発生しないはずです。

例外をキャッチした場合でも、どうすれば休止状態をクリーンに再初期化できますか?(これまでのところ、c3p0を使用せずに、セッションファクトリを再構築しただけですが、接続がリークする可能性がある場合でも驚かないでしょう(またはそうしても大丈夫ですか?))。

データベースはVirtuosoオープンソース版です。

私のhibernate.xml.cfgc3p0構成:

<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>  
<property name="hibernate.c3p0.breakAfterAcquireFailure">false</property>
<property name="hibernate.c3p0.acquireRetryAttempts">-1</property>
<property name="hibernate.c3p0.acquireRetryDelay">30000</property>
<property name="hibernate.c3p0.automaticTestTable">my_test_table</property>

<property name="hibernate.c3p0.initialPoolSize">3</property>
<property name="hibernate.c3p0.minPoolSize">3</property>
<property name="hibernate.c3p0.maxPoolSize">10</property>

ところで:テストテーブルが作成され、大量のデバッグ出力が得られるので、実際に構成を読み取っているようです。

4

4 に答える 4

3

私が間違っていない場合、これは接続プールが私のためにできることの1つです。データベースに問題がある場合は、接続を再試行してください。最悪の場合、無限大です。

あなたは間違っています。接続プールは単なる接続プールであり、データベースへのすでに確立された物理接続がいくつか含まれており、必要なときにこれらの接続を作成するオーバーヘッドを回避するために使用されます。

そうは言っても、これらの接続は古くなる可能性があります(たとえば、データベースを再起動した場合)。幸い、ほとんどの接続プールは、接続がまだ有効かどうかをテストし、配布する前に更新するように構成できます。c3p0は、接続テストの構成で説明されているようにこの機能をサポートしており、実際にはすでにさまざまなオプションの1つを使用しています。したがって、データベースが戻ってきたときに接続を更新する必要があります。

ただし、データベースがダウンしたときにアプリケーションが魔法のように中断されることを期待しないでください。プールはこれを行いません。

于 2009-10-30T23:06:54.533 に答える
1

BoneCP は実際にこれを実装しているようです。トランザクションを記録し、ネットワークまたはデータベースの障害時に再生するように設定できます。

http://jolbox.com/bonecp/downloads/site/apidocs/com/jolbox/bonecp/BoneCPConfig.html#setTransactionRecoveryEnabled(ブール値)

于 2010-06-12T14:48:41.307 に答える
0

答えてくれてありがとう。セクションの最後の段落を本当に理解していないようです http://www.mchange.com/projects/c3p0/index.html#configuring_recovery

最初はc3p0がそれを実行できるように見えるため(古い接続を検出し、アプリケーションコードに例外をスローすることなく永遠に接続を再試行します(もちろん、接続ではなくSQLステートメントに関連するエラーでない限り)、しかし、最後のパラグラフ (かなり紛らわしい方法で書かれています) では、c3p0 はそれを 100% 保証できないようです。

したがって、私の解決策は、jdbc Connection インターフェイスから必要なメソッドの小さなラッパーを作成することでした。これは、接続エラーのためにクエリが失敗した場合に再接続を試みます。もちろん、コンポーネントに独自のインターフェースではなく標準の接続インターフェースを使用させたいので、少しハックですが、少なくとも今はきれいに動作しています。

于 2009-11-02T10:25:21.693 に答える
0

あなたは忘れています:

  • 開始された取引はどうですか?
  • すでに DB に送信された準備済みステートメントはどうなりますか?

したがって、アプリケーションはトランザクションを再開する必要があります。私が考えることができる唯一の方法は、接続プールが接続ハンドルへのすべての呼び出しを追跡し、エラーが発生した場合にそれらを再生することですが、これにより接続プールが大幅に遅くなります。

BoneCP ( http://jolbox.com ) の場合、プールは最初に JDBC ドライバーによってスローされた例外をキャッチし、その接続に障害があるというフラグを立てるか、接続プール全体を再作成することによって処理することによって、障害が発生したことを検出します。 .

編集:現在処理中です。

于 2009-11-11T14:40:50.240 に答える