Исключение прерывания (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 - [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.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)