Проблема тупика в DBCP, развернутом на Tomcat - PullRequest
17 голосов
/ 19 апреля 2011

Я использую источник данных DBCP (с конфигурацией по умолчанию) в конфигурации Spring для управления своими соединениями с базой данных, и я нахожусь в тупиковой ситуации, когда количество клиентов увеличивается.

Я обнаружил, что в DBCP 1.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)

Любые предложения приветствуются!

Ответы [ 5 ]

8 голосов
/ 19 апреля 2011

Я перешел на c3p0 , несколько лет назад. Вы можете попробовать это. Я полагаю, вам не нужно было сильно менять, это всего лишь игра конфигурации.

Несколько связанный поток, Опции пула соединений с JDBC: DBCP против C3P0 . Ну, на самом деле я связал это.

[отредактировано 19/10/12]

Tomcat 7 имеет приличный пул соединений, Tomcat JDBC Connection Pool .

1 голос
/ 16 октября 2012

Увеличение нагрузки на приложение увеличивает требования к одновременным соединениям.Поскольку ваши потоки зависают на borrowConnection() - это означает, что у вас недостаточно ActiveConnections доступных.

Увеличение maxActive в свойствах вашего источника данных и установите WHEN_EXHAUSTED_BLOCK на некоторое время, например 600ms - 1000ms.Вы получите исключение No element available только по истечении 600 мс -1000 мс.

1 голос
/ 19 апреля 2011

Вы убедились, что версия commons-pool соответствует версии dbcp?

Кроме того, я не вижу тупика в трассировке стека, просто похоже, что у вас есть потоки, ожидающие освобождения соединений. Сколько потоков вы пытаетесь подключить одновременно? Сколько соединений вы настроили для пула и т.д ..?

При отладке подобных случаев полезно также посмотреть, что делают потоки, получившие соединение.

0 голосов
/ 26 сентября 2017

Я столкнулся с похожими проблемами, и это было решено с помощью следующих шагов

  1. Закрыть все ресурсы базы данных в правильной последовательности

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

Различные драйверы реализованы по-разному, некоторые драйверы все равно будут подключены к соединению, если базовый набор результатов не закрыт.

  1. Необходимо настроить значения по умолчанию для Apache DBCP

dataSource.setDefaultAutoCommit(true);<br> 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);

Убедитесь, что сервер базы данных может разрешить как минимум 50+ подключений больше, чем число, указанное в setMaxActive, поскольку dbcp сначала дает x новых подключений, а затем пытается очистить подключения, превышающие setMaxActive число. При очистке dbcp показывает, какие соединения не были закрыты в журнале / консоли сервера.

0 голосов
/ 24 июля 2012

Я думаю, что это вызвано тем, что соединения не закрываются в коде вашего приложения, поэтому у вас просто закончились соединения в пуле. Возможно, вам следует попытаться установить свойство «removeAbandoned» в DBCP. Это задокументировано в http://commons.apache.org/dbcp/configuration.html как

Установка этого значения в true может восстановить соединения БД из плохо написанных приложений. который не может закрыть соединение.

Удачи!

...