17

Spring構成でDBCPデータソース(デフォルト構成)を使用してデータベースへの接続を管理していますが、クライアントの数が増えるとデッドロック状態になります。

私が使用していたDBCP1.2.1にデッドロックの問題があることがわかりました。これは、1.4で解決されるはずでした。そのため、1.4にアップグレードしましたが、問題は解決しません。

スレッドダンプには、次のスタックトレースでブロックされた多くのスレッドがあります。

   java.lang.Thread.State: WAITING on org.apache.commons.pool.impl.GenericObjectPool$Latch@b6b09e
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1104)
at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:106)
at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:200)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:350)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:261)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:101)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:160)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:631)

どんな提案でも大歓迎です!

4

5 に答える 5

8

数年前にc3p0に切り替えました。あなたはそれを試すことができます。あまり変更する必要はなかったと思います。これは単なる構成のゲームです。

やや関連するスレッド、JDBCを使用した接続プールオプション:DBCPとC3P0。ええと、実際に私はそれを関連させました。

[編集、19/10/12]

Tomcat 7には、適切な接続プールであるTomcatJDBC接続プールがあります

于 2011-04-19T10:36:21.940 に答える
1

commons-poolのバージョンがdbcpのバージョンと一致していることを確認しましたか?

また、スタックトレースにデッドロックが表示されていません。接続が解放されるのを待機しているスレッドがあるようです。同時に接続しようとしているスレッドの数はいくつですか。プールなどに接続をいくつ設定しましたか?

この種のケースをデバッグする際には、接続を取得したスレッドが何を行っているかを確認することも役立ちます。

于 2011-04-19T10:42:19.270 に答える
1

アプリケーションの負荷が増えると、同時接続に対する要件が増えます。あなたのスレッドがぶら下がってborrowConnection()いるので-あなたが十分にActiveConnections利用可能になっていないことを意味します。

maxActiveデータソースのプロパティを増やして、のように設定しWHEN_EXHAUSTED_BLOCKます600ms - 1000msNo element available600ms〜1000ms経過した後にのみ例外が発生します。

于 2012-10-15T20:27:21.717 に答える
0

これは、アプリコードで接続を閉じていないことが原因だと思います。そのため、プール内の接続が不足しているだけです。たぶん、DBCPで「removeAbandoned」プロパティを設定してみてください。これは、http://commons.apache.org/dbcp/configuration.htmlに次のように文書化されています。

これをtrueに設定すると、接続を閉じることができない不適切に記述されたアプリケーションからdb接続を回復できます。

頑張ってください!

于 2012-07-24T12:59:18.377 に答える
0

私は同様の問題に直面していましたが、これは次の手順で解決されました

  1. すべてのデータベースリソースを適切な順序で閉じます

    resultSet.close();
    statement.close();
    connection.close();
    

異なるドライバーは異なる方法で実装されますが、基になるresultSetが閉じられていない場合でも、一部のドライバーは接続をハンドオンします。

  1. ApacheDBCPのデフォルトを調整する必要があります

dataSource.setDefaultAutoCommit(true);
dataSource.setMaxActive(700); // make sure db server has it 800 dataSource.setRemoveAbandoned(true); dataSource.setTestOnBorrow(true); dataSource.setLogAbandoned(true); dataSource.setTestWhileIdle(true); dataSource.setTestOnReturn(true); dataSource.setRemoveAbandonedTimeout(60);

setMaxActivedbcpがx最初に新しい接続を提供し、次に数を超える接続をクリーンアップしようとするため、データベースサーバーがで指定された数を超える少なくとも50以上の接続を許可できることを確認してくださいsetMaxActiveクリーンアップ時に、dbcpは、サーバーログ/コンソールで閉じられなかったすべての接続を示します。

于 2017-09-26T07:21:09.540 に答える