2009-12-11 31 views
8

私のアプリケーションでは、Springはデータベースアクセス用の接続プールを管理します。 Hibernateは、これらの接続をそのクエリに使用します。一見すると、プールには問題はありません。これは、同時接続のクライアントと1つの接続のみを持つプールで正しく動作します。私は多くのクエリを実行することができるので、私は(または春)オープンな接続を残していないと思う。非アクティブ時に接続がハングアップする

私の問題は、しばらく時間がないと表示されます(時には30分、時には2時間以上)。そして、Hibernateが検索を行うと、それはあまりにも多く持続します。 log4jレベルをTRACEに設定すると、ログが取得されます。

... 
18:27:01 DEBUG nsactionSynchronizationManager - Retrieved value [[email protected]] for key [[email protected]] bound to thread [http-8080-Processor24] 
18:27:01 DEBUG HibernateTransactionManager  - Found thread-bound Session [[email protected]] for Hibernate transaction 
18:27:01 DEBUG HibernateTransactionManager  - Using transaction object [org.springframework.orm.hi[email protected]1b2ffee] 
18:27:01 DEBUG HibernateTransactionManager  - Creating new transaction with name [com.acjoventut.service.GenericManager.findByExample]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT 
18:27:01 DEBUG HibernateTransactionManager  - Preparing JDBC Connection of Hibernate Session [[email protected]] 
18:27:01 TRACE SessionImpl      - setting flush mode to: AUTO 
18:27:01 DEBUG JDBCTransaction     - begin 
18:27:01 DEBUG ConnectionManager    - opening JDBC connection 

ここで約2〜10分間凍結します。しかし、次に続行します:

18:30:11 DEBUG JDBCTransaction     - current autocommit status: true 
18:30:11 DEBUG JDBCTransaction     - disabling autocommit 
18:30:11 TRACE JDBCContext      - after transaction begin 
18:30:11 DEBUG HibernateTransactionManager  - Exposing Hibernate transaction as JDBC transaction [jdbc:oracle:thin:@212.31.39.50:30998:orcl, UserName=DEVELOP, Oracle JDBC driver] 
18:30:11 DEBUG nsactionSynchronizationManager - Bound value [[email protected]] for key [[email protected]] to thread [http-8080-Processor24] 
18:30:11 DEBUG nsactionSynchronizationManager - Initializing transaction synchronization 
... 

その後、別の非アクティブ期間まで問題なく動作します。 IMHO、それは接続プールが無効な/閉じられた接続を返すように思え、Hibernateがそれを認識すると、プールへの別の接続を尋ねます。

私は、この問題やそれを区切るためにできることをどのように解決できるのか分かりません。これを達成するための助けに感謝します。

ありがとうございました。

編集:まあ、それは最終的にファイアウォールのルールのためです。データベースは接続が失われたことを検出しますが、プール(dbcpまたはc3p0)は失われていません。したがって、成功なしでデータベースに照会しようとします。まだ私にとって奇妙なのは、タイムアウト期間が非常に可変であるということです。おそらく、ルールが異常に奇妙であるか、ファイアウォールが正しく機能しない可能性があります。とにかく、私はそのマシンにアクセスできず、説明を待つだけです。 :(

+0

これがファイアウォールの問題であるかどうかをどのように特定しましたか?私は似たような問題に直面しています。dbcpはSpringバッチトランザクションで無期限にハングし、戻ってくることはありません。 – YogendraJ

答えて

7

データベースが別のボックスにあり、その間にファイアウォールが設定されているときにこれまでに問題が発生しました。これは、すぐに閉じてください。アイドル接続をタイムアウトする。

状況によってはファイアウォールは、JDBCエンドが検出しないように接続を切断し、それを使用しようとすると、不定ブロックになります。

私の場合は、プールから返す前にテストクエリを送信したカスタム接続プールでした。私はこのテストクエリが(Statement.setQueryTimeoutを使って)タイムアウトするように設定して、無期限にブロックしないようにしました。

+0

カスタムプールを使用してテストクエリのみを送信する理由がわかりません。ややまともな接続プールやコンテナ管理されたデータソースがすでにこれに対応しています。例えばDBCPやTomcatのJNDIもそうです。それぞれのキーワード 'validationQuery'の下でconfig文書を参照してください。 – BalusC

+0

これは、別の接続プールを使用し、実際にDBCPのvalidationQueryと同様のことをしたコードのセクションにあるプロジェクト(長い間ずっと前)でした。 – Joe

+0

あなたは正しいです。問題はファイアウォールのルールの一部ではないようです。私は、最良のソリューションはファイアウォールの動作を変更すると思う。ありがとう。 – sinuhepop

1

があなたのプールの実装の設定を確認してください。通常は、それはそれを閉じます後、各接続のためのa timeoutを持っていApache DBCPです。あなたのコードで

を、あなたの周りの接続を維持するべきではありません。1を取得し、

+0

Springは私の接続を管理していますので、明示的にConnection.close()を呼び出さなければなりません。私ですか?あなたが言うように、destroy-method = "close"でorg.apache.commons.dbcp.BasicDataSourceを使用しています。私はそれについて研究します。 – sinuhepop

+1

他にも2つの問題があります。あなたとデータベースサーバーの間にファイアウォールが存在する可能性があります(アイドル状態のTCP接続では2時間のタイムアウトが少し短くなります)。または、しばらくしてアイドル状態の接続を閉じるようにデータベースが構成されている。デッド接続をチェックし、DBを定期的にpingしてパイプを開いたままにするには、DBCPの他の設定オプションを参照してください。 –

+0

閉じる:いいえ、閉じてはいけませんが、トランザクションを終了する必要があります(これにより、接続がプールに返されることがSpringに分かります)。 –

1

アイドルタイムアウトの問題を解決する1つの方法は、1つがアクティブでもう1つがスタンバイ(まだ接続が作成されていません)のデュアル接続プールを持つことです。 FIREWALL_IDLE_TIMEOUTよりもはるかに少ないトリガー時間を持つタイマーを用意し、接続プールを切り替えます。私はこれとITS WORKINGを試しました。

1

あなたがデータソースにいくつかのパラメータを追加する必要があります。

より重要な追加testOnBorrowとvalidationQuery

1

我々はまた、判明同様の症状を持つ問題を解決しましたファイアウォールによって引き起こされる可能性があります。

接続がアイドル状態にならないようにするtestWhileIdle接続プールプロパティを変更し、ファイアウォールが接続をシャットダウンすることによって、この問題を回避することができました。 Apache commons dbcp BasicDataSourceを参照してください。ほとんどの場合、我々は唯一のtestWhileIdle(デフォルトはfalse)を追加する必要が

<property name="testWhileIdle"> 
    <value>true</value> 
</property> 
<property name="minEvictableIdleTimeMillis"> 
    <value>600000</value> 
</property> 
<property name="timeBetweenEvictionRunsMillis"> 
    <value>600000</value> 
</property> 

が、良い対策のために、他の2つのプロパティを追加:ここでの問題を修正し、構成ファイルから発揮、persistentce-のcontext.xmlであります。

ここでは、私たちが見ていたいくつかのログを示します。このデバッグログでは、接続を使用する前に接続を開くまでに16分かかり、すべてがハングする原因になります。追跡が困難なエラーはありませんでした。

09-06-13 @ 16:36:34 [DEBUG] HibernateTransactionManager - Preparing JDBC Connection of Hibernate Session [[email protected]] 
09-06-13 @ 16:36:34 [DEBUG] ConnectionManager - opening JDBC connection 
09-06-13 @ 16:52:00 [DEBUG] DataSourceUtils - Setting JDBC Connection 
09-06-13 @ 16:52:00 [DEBUG] JDBCTransaction - begin 
09-06-13 @ 16:52:00 [DEBUG] JDBCTransaction - current autocommit status: true 
関連する問題