В последних версиях DBCP и C3P0, использующих поддержку Spring Ibatis, я сталкиваюсь с проблемой утечки соединений.
Сценарий состоит в том, что в журнале работает SQL, который блокирует несколько таблиц. Это приводит к тому, что количество подключений в моем пуле становится максимальным, поскольку пользователи запускают запросы, которые попадают в заблокированные таблицы. Наконец, администратор заходит в MySQL и делает kill query <id>
на долгосрочном SQL.
Если имеется достаточно потоков (в моем случае около 50 или более), ожидающих возврата потока БД в пул, то я вижу что-то вроде следующего в дампе потока:
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1315)
at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:557)
- locked <0x00002aaacbb01118> (a com.mchange.v2.resourcepool.BasicResourcePool)
at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:477)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:525)
at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128)
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:113)
at
или
java.lang.Thread.State: WAITING (on object monitor)
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)
- locked <0x00002aab0f030620> (a org.apache.commons.pool.impl.GenericObjectPool$Latch)
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.DataSourceUtils.doGetConnection(DataSourceUtils.java:113)
at
и эти темы ждут ВСЕГДА.
Этого не происходит, если пул исчерпан, и только несколько (около 5) потоков ожидают свободного соединения в пуле.
Я знаю, что есть конфигурация, которая может решить эту проблему (установка времени ожидания и т. Д.), Но меня интересует, почему это происходит в первую очередь? Почему активные потоки не возвращаются в пул, когда существует 50 или более потоков, ожидающих соединения, и я уничтожаю долго работающий SQL?
Обновление: Я должен был дать понять, что использую Spring 3.0.2 и
Ибатис 2.3. Я использую SqlMapClientTemplate, который управляет моим
связи для меня. На данный момент, я начинаю думать, что это
Ibatis 2.3 не справляется с тяжелыми грузами правильно.