C3P0 поточно-ориентирован? - PullRequest
12 голосов
/ 16 февраля 2011

Исключение прерывания (java.lang.InterruptedException) происходит, когда я пытаюсь выполнить некоторые простые операции чтения (SELECT) с использованием C3P0 в базе данных MySQL.Исключение происходит, когда я увеличиваю количество параллельных потоков более чем на 100 (я пробовал с 5,10,20,60 и 100).Оператор, который я выполняю, прост:

SELECT `Model.id` FROM `Model` LIMIT 100;

Мои соединения объединяются в пул из ComboPooledDataSource, который настроен с использованием следующих свойств (см. Также руководство C3P0 ):

c3p0.jdbcUrl=jdbc:mysql... 
c3p0.debugUnreturnedConnectionStackTraces=true
c3p0.maxIdleTime=5
c3p0.maxPoolSize=1000
c3p0.minPoolSize=5
c3p0.initialPoolSize=5
c3p0.acquireIncrement=3
c3p0.acquireRetryAttempts=50
c3p0.numHelperThreads=20
c3p0.checkoutTimeout=0
c3p0.testConnectionOnCheckin=true
c3p0.testConnectionOnCheckout=true
user=***
password=***

Сервер MySQL на компьютере, на котором я запускаю тесты, настроен на прием 1024 подключений, и выполняемые мной модульные тесты успешно выполнены (данные извлекаются из базы данных, как и ожидалось).Однако в файле журнала C3P0 я нахожу следующее предупреждение:

15:36:11,449  WARN BasicResourcePool:1876 - com.mchange.v2.resourcepool.BasicResourcePool@9ba6076 -- Thread unexpectedly interrupted while performing an acquisition attempt.
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1805)
    at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)

Я хотел бы знать причину этого предупреждения и, во-вторых, его возможное влияние на надежность и стабильность программного обеспечения.Обратите внимание, что после использования я закрываю набор результатов, инструкцию SQL и соединение.Наконец, когда тест закончен, я закрываю пул, вызывая метод ComboPooledDataSource#close().Что более странно (и, похоже, выявляет проблему синхронизации), так это то, что если я уделю пулу достаточно времени, используя следующее ...

Thread.sleep(10000); // wait for some time
datasource.close();

Никаких предупреждений в журналах не будет!Как вы думаете, это поднимает проблему безопасности потоков для C3P0 или я что-то делаю неправильно?

Обновление 1:

Позвольте мне упомянуть, что удаление Thread.sleep(10000)Помимо того, что уже упоминалось, в журнале MySQL регистрируется следующая информация:

110221 14:57:13 [Warning] Aborted connection 9762 to db: 'myDatabase' user: 'root'
host: 'localhost' (Got an error reading communication packets)

Может пролить немного света ...

Обновление 2:

Вот моя конфигурация сервера MySQL.Максимально допустимое количество подключений к серверу установлено в 1024 (как я уже упоминал выше), что достаточно для того, что я пытаюсь сделать.

[mysqld]
max_allowed_packet  = 64M
thread_concurrency      = 8
thread_cache_size       = 8
thread_stack        = 192K
query_cache_size = 0
query_cache_type = 0
max_connections = 1024
back_log = 50
innodb_thread_concurrency = 6
innodb_lock_wait_timeout = 120
log_warnings

Чтобы скрыть какие-либо сомнения, я проверил, что максимальное количество соединений правильно установлено с помощью:

show global variables where Variable_name='max_connections';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 1024  | 
+-----------------+-------+
1 row in set (0.00 sec)

Ответы [ 3 ]

6 голосов
/ 21 февраля 2011

Это предупреждение приходит примерно в строке 2007 здесь . Кажется, что нить застряла при попытке установить соединение.

Возможно, потому что пул настроен для получения большего количества соединений, чем то, для чего настроен ваш сервер MySQL. Кажется, это имеет смысл, поскольку значение по умолчанию max_connection равно 100 (или 151 в зависимости от вашей версии mysql)

Так что поток, пытающийся установить соединение, входит в цикл сна () / повторной попытки, пытающийся получить соединение соединение - однако вы закрываете весь пул, пока он находится внутри этого цикла - этот поток прерывается, поэтому при закрытии пула можно восстановить все ресурсы.

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

1 голос
/ 22 июня 2012

Я только столкнулся с этой проблемой.Вот мой параметр для источника данных:

 [java:comp/env/jdbc/pooledDS] = [com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 2siwtu8o4m410i1l4tkxb|187c55c, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> null, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 2siwtu8o4m410i1l4tkxb|187c55c, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> null, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 15, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> null, properties -> {}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]]

и исправлено:

[java:comp/env/jdbc/pooledDS] = [com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 2siwtu8o4m5kux117kgtx|13e754f, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> oracle.jdbc.driver.OracleDriver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 2siwtu8o4m5kux117kgtx|13e754f, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:oracle:thin:@localhost:1521:oracle, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 15, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]]

Так что не все было установлено правильно.Более конкретно, когда я вызвал setDriverClass и setJdbcUrl для исправления нулевых значений, я исключил InterruptedException

1 голос
/ 16 февраля 2011

Возможно, InterruptedException нормально, потому что некоторые потоки c3p0 ожидают соединения, и когда вы вызываете close(), эти потоки прерываются. Хотя, согласно вашей настройке (100 клиентов, 1000 подключений к серверу), такая необходимость ожидания ресурса не так очевидна.
Если вы действительно заинтересованы, наиболее надежным решением будет поиск журналов c3p0, возможно, добавление еще журналов и перекомпиляция ...

...