2017-09-06 11 views
0

c3p0の設定時に問題が発生しました。シナリオは:私は毎日午前3時に開始され、次に何かをするためにデータベースに接続する1つのjavaプロジェクトを持っています。場合によっては、その時点でデータベースがダウンしている可能性があり、2〜3時間後に回復する可能性があります。
ですから、データベースに正常に接続できるようになるまで、特定の時間間隔でデータベースを再接続して、データベースが正常かどうかを確認する必要があります。 成功するまでデータベースを無限に再接続するようにc3p0を設定しようとしましたが、デッドロックが発生しているようです。以下は私のc3p0の設定です。 Springフレームワークでc3p0 v0.9.1をhibernateで使用します。データベースはDB2です。データベースがダウンしているときにC3p0がデータベースの再接続に失敗しました

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" > 
    <property name="driverClass" value="${jdbc.driverClassName}"/> 
    <property name="jdbcUrl" value="${jdbc.url}"/> 
    <property name="user" value="root"/> 
    <property name="password" value="root"/> 

    <property name="acquireRetryAttempts" value="0"/> 

    <property name="acquireRetryDelay" value="10000"/> 

    <property name="maxIdleTime"value="60"/> 
    <property name="minPoolSize" value="5" /> 
    <property name="maxPoolSize" value="200"/> 
    <property name="idleConnectionTestPeriod" value="30" /> 
    <property name="preferredTestQuery" value="values(1)" /> 
</bean> 

私はプログラムを実行すると、それは失敗し、エラーログを以下に示します。

[WARN]: com[email protected]21eb3f -- APPARENT DEADLOCK!!! 
Creating emergency threads for unassigned pending tasks! 
[WARN]: com[email protected]21eb3f -- APPARENT DEADLOCK!!! 
Complete Status: 
Managed Threads: 3 
Active Threads: 3 
Active Tasks: 
    [email protected]d (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0) 
    [email protected]c (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1) 
    [email protected]3 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2) 
Pending Tasks: 
    [email protected]4 
    [email protected]0 
    [email protected] 
    [email protected]2 
    [email protected] 
    [email protected] 
    [email protected] 
Pool thread stack traces: 
    ... 
[WARN] [2017-09-04 ThreadPoolAsynchronousRunner.processReplacedThreads() ] Task [email protected] 
(in deadlocked PoolThread) failed to complete in maximum time 60000ms. Trying interrupt(). 
[WARN] [2017-09-04 ThreadPoolAsynchronousRunner.processReplacedThreads() ] Task [email protected] 
(in deadlocked PoolThread) failed to complete in maximum time 60000ms. Trying interrupt(). 
[WARN] [2017-09-04 ThreadPoolAsynchronousRunner.processReplacedThreads() ] Task [email protected] 
(in deadlocked PoolThread) failed to complete in maximum time 60000ms. Trying interrupt(). 

[WARN] [2017-09-04 BasicResourcePool$AcquireTask.run()] [email protected] -- Thread unexpectedly interrupted 
while performing an acquisition attempt. 
java.lang.InterruptedException: sleep interrupted 
    at java.lang.Thread.sleep(Native Method) 
    at com.mchange.v2.resourcepol.BasicResourcePool$AcquireTask.run (BasicResourcePool.java:1805) 
    at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547) 
[WARN] [2017-09-04 BasicResourcePool$AcquireTask.run()] [email protected] -- Thread unexpectedly interrupted 
while performing an acquisition attempt. 
java.lang.InterruptedException: sleep interrupted 
    at java.lang.Thread.sleep(Native Method) 
    at com.mchange.v2.resourcepol.BasicResourcePool$AcquireTask.run (BasicResourcePool.java:1805) 
    at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547) 
[WARN] [2017-09-04 BasicResourcePool$AcquireTask.run()] [email protected] -- Thread unexpectedly interrupted 
while performing an acquisition attempt. 
java.lang.InterruptedException: sleep interrupted 
    at java.lang.Thread.sleep(Native Method) 
    at com.mchange.v2.resourcepol.BasicResourcePool$AcquireTask.run (BasicResourcePool.java:1805) 
    at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547) 

あなたは設定が間違っている何かを持っている場合、私を修正するために助けてくださいもらえますか?前もって感謝します!

+0

この 'application'はどのように起動しましたか? cron? –

+0

@スカリーはい、そうです。 – cmjauto

+0

次に、ツールを使用してみることができますか?あなたのアプリを起動しようとする前にDBがアップしているかどうかをテストして、これをあなたのアプリ起動スクリプト –

答えて

0

まず、c3p0-0.9.1を使用しないでください。それは古代です。現在のバージョンは0.9.5.2です。

ここで問題となるのは、データベースがダウンしているときに、接続の試行が例外で失敗していないことです。ハングアップしています。だから、c3p0のスレッドプールは成功しても失敗しても無期限にハングアップしないコネクションを獲得しようとしています。スレッドプールが完全に飽和してしばらくブロックされると、c3p0はAPPART DEADLOCKを宣言し、あなたが見たものを見ます。

あなたのネットワークやサーバーに問題があり、データベースに接続しようとすると、成功または失敗するのではなくハングアップする問題を修正することをお勧めします。これを解決できれば、おそらく問題はなくなります。

解決できない場合は、c3p0の設定maxAdministrativeTaskTimeを使用して問題を回避することができます。これを設定すると、定義した秒数の後に、c3p0はConnection取得のようなハングアップタスクを壊してしまい、タスクがハングしたスレッドでinterrupt()を呼び出して強制的に失敗させようとします。あなたが運が良ければ、フリー・アクイジション・タスクは失敗し、InterruptedExceptionとなり、人生は続くでしょう。

maxAdministrativeTaskTimeを使用している場合は、データベースへの接続よりもかなり長い値を設定することをお勧めします(DBMSが稼働している間に)。 numHelperThreadsをデフォルト値の3から増やして、スレッドプール全体を飽和させてデッドロックを引き起こす前に、無限にぶら下がっていてもまだまだ不十分な取得タスクでより多くのスレッドを再生できるようにします。

+0

詳細な説明をいただき、ありがとうございます。私はあなたの提案で新しいバージョンを試してみます。 – cmjauto

関連する問題