質問

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

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

しかし、代わりに私は壊れたパイプ例外を受け取り、時には接続が拒否され、その後例外が自分のコードに渡されますが、これは起こりません。

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

データベースはVirtuosoオープンソースエディションです。

my hibernate.xml.cfg c3p0 config:

<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>

btw:テストテーブルが作成され、大量のデバッグ出力が得られるため、実際に設定を読み取るようです。

役に立ちましたか?

解決

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

http:// jolbox.com/bonecp/downloads/site/apidocs/com/jolbox/bonecp/BoneCPConfig.html#setTransactionRecoveryEnabled(boolean)

他のヒント

  

間違っていない場合、これは接続プールが私にできることの1つです。dbに問題がある場合は、接続を再試行します-最悪の場合は無限大です。

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

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

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

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

最初はc3p0がそれを行うことができるようだ(古い接続を検出し、アプリケーションコードに例外をスローすることなく、永遠に接続の取得を再試行します(もちろん、SQLステートメントに関連するエラーではなく、接続)、しかし最後の段落では-かなり混乱した方法で書かれています-c3p0はそれを100%に保証できないかのようです。

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

忘れている:

  • 開始されたトランザクションはどうですか?
  • DBに既に送信されている準備済みステートメントについてはどうですか?
  • etc

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

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

編集:現在処理中です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top