c3p0 зависает на getConnection при сбое сети

Я использую c3p0 ComboPooledDataSource для объединения соединений с базой данных (к базе данных Oracle 10g). У меня проблемы с обработкой сбоев подключения к базе данных.

Если нет соединения с базой данных, когда устанавливается первое соединение, срабатывает тайм-аут проверки, и происходит сбой, как и ожидалось.

Однако, если обрыв соединения происходит после того, как одно или несколько соединений были получены и уже находятся в пуле соединений, вызов getConnection() просто зависает. Никаких исключений не выбрасывается. Я предполагаю, что это связано с тем, что он пытается использовать объединенное соединение, но это соединение больше не работает.

Есть ли способ проверить, действительно ли соединение, прежде чем пытаться его использовать? Я попытался установить testConnectionOnCheckout=true, но, похоже, это не имеет никакого эффекта.

Это дамп темы

C3P0PooledConnectionPoolManager[identityToken->2rvy8f8x1oujxrx1majv5s|be41d5]- HelperThread-#2" демон prio=6 tid=0x0307a800 nid=0x840 в Object.wait() [0x03d1f000] java.lang.Thread.State: TIMED_WAITING (на мониторе объекта) at (на объектном мониторе) .lang.Object.wait (собственный метод) — ожидание ‹0x28387f88> (com.mchange.v2.async.ThreadPoolAsynchronousRunner) в com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:635) — заблокировано ‹0x28387f88> (com.mchange.v2.async.ThreadPoolAsynchronousRunner)

Блокированные собственные синхронизаторы: - Нет


person Sam    schedule 21.10.2013    source источник
comment
можно дамп трассировки стека во время зависания, чтобы посмотреть, на чем конкретно висят клиенты? благодаря. нет условия, при котором клиенты должны бесконечно зависать на getConnection(), если установлен checkoutTimout.   -  person Steve Waldman    schedule 21.10.2013
comment
Спасибо за ответ, добавил дамп темы. CheckoutTimeout работает нормально, если при первом подключении нет соединения с БД. Зависание происходит только тогда, когда я пытаюсь проверить «мертвое» соединение.   -  person Sam    schedule 21.10.2013
comment
Привет. это внутренний вспомогательный поток c3p0, ожидающий выполнения задач. все в порядке. нам нужны дампы замороженных клиентских потоков. Благодарность!   -  person Steve Waldman    schedule 21.10.2013


Ответы (1)


Я столкнулся с той же проблемой. В моем случае это было вызвано тем, что драйвер JDBC не был настроен на тайм-аут при сбоях сокета. Я сделал следующие дополнения к моей конфигурации C3P0 ComboPooledDataSource:

cpds = new ComboPooledDataSource();
...

//--------------------------------------------------------------------------------------
// NOTE: Once you decide to use cpds.setProperties() to set some connection properties,
//       all properties must be set, including user/password, otherwise an exception
//       will be thrown
Properties prop = new Properties();
prop.setProperty("oracle.net.CONNECT_TIMEOUT",
    Integer.toString(JDBC_CONNECTION_TIMEOUT_IN_MILLISECONDS));
prop.setProperty("oracle.jdbc.ReadTimeout",
    Integer.toString(JDBC_SOCKET_TIMEOUT_IN_MILLISECONDS));
prop.setProperty("user", username);
prop.setProperty("password", password);
cpds.setProperties(prop);
//--------------------------------------------------------------------------------------

...

Свойства драйвера Oracle применяются, когда C3P0 создает объект Connection. Эти два свойства, в частности, вызовут исключение, если соединение сокета неактивно более 30 секунд.

Если вы не подключаетесь к базе данных Oracle, существуют аналогичные свойства для других драйверов JDBC для других поставщиков баз данных. Некоторые из них показаны внизу этого страница.

person Jim Tough    schedule 10.02.2015