2015-10-15 2 views
1

Я разрабатываю веб-приложение на Tomcat 8 с Maven, я использую c3p0 для обработки соединений в основном потоке и на двух других параллельных потоках, мой класс менеджера соединений спрашивает класс DataSource одноплодного я реализовал для синхронных соединений, например, такTomcat8 + c3p0, соединения прерываются и закрываются автоматически

public synchronized Connection getConnection() { 
    try { 
     return cpds.getConnection(); 
    } catch (SQLException ex) { 
     logger.error("Error while issuing a pooled connection", ex); 
    } 
    return null; 
} 

, но когда я пытаюсь использовать эти соединения они начинают либо прерывать

09:47:17.164 [QuartzScheduler_Worker-4] ERROR com.myapp.providers.DataSource - Error while issuing a pooled connection 
java.sql.SQLException: An SQLException was provoked by the following failure: java.lang.InterruptedException 
    at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:106) ~[c3p0-0.9.1.2.jar:0.9.1.2] 
    at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:65) ~[c3p0-0.9.1.2.jar:0.9.1.2] 
    at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:62) ~[c3p0-0.9.1.2.jar:0.9.1.2] 
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:531) ~[c3p0-0.9.1.2.jar:0.9.1.2] 
    at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128) ~[c3p0-0.9.1.2.jar:0.9.1.2] 

или закрыть в середине транзакции и нарушения любых операторов и наборов результатов, которые е используются в то время

Я конфигурирование объекта DataSource, как так

cpds = new ComboPooledDataSource(); 
     cpds.setDriverClass(oracle.jdbc.driver.OracleDriver); 
     cpds.setJdbcUrl(jdbc:oracle:thin:@xx.xxx.xxx.xxx:1521:XE); 
     cpds.setUser("username"); 
     cpds.setPassword("password"); 

     // database connection properties 
     cpds.setInitialPoolSize(10); 
     cpds.setAcquireIncrement(3); 
     cpds.setMaxPoolSize(100); 
     cpds.setMinPoolSize(15); 
     cpds.setMaxStatements(75); 

     // connection pool preferences 
     cpds.setIdleConnectionTestPeriod(60); 
     cpds.setMaxIdleTime(30000); 
     cpds.setAutoCommitOnClose(false); 
     cpds.setPreferredTestQuery("SELECT 1 FROM DUAL"); 
     cpds.setTestConnectionOnCheckin(false); 
     cpds.setTestConnectionOnCheckout(false); 
     cpds.setAcquireRetryAttempts(30); 
     cpds.setAcquireRetryDelay(1000); 
     cpds.setBreakAfterAcquireFailure(false); 

Я также написал небольшой тестовый метод, который работает в цикле и запросы к базе данных для п раз, но это работа хорошо.

+1

Где ваша конфигурация crp0? –

+0

Я настраиваю его программно, я отредактирую его в секундах – svarog

+1

в ответе @Steve Waldman, он указывает на поток, который был повешен, так что вы используете разные потоки, чтобы открыть соединение и использовать связь ? Если вы используете соединение в потоке, который не является контекстом (это означает, что tomcat не знает его существования), когда другой поток запрашивает соединение из пула, tomcat агрессивно прерывает первый поток, чтобы передать соединение второй поток – AntJavaDev

ответ

2

c3p0-0.9.1.2 очень, очень старый; рассмотрите возможность обновления до версии 0.9.5.1, текущей версии.

Проблема как ясная, так и не очень ясная. Явная часть заключается в том, что что-то вызывает interrupt() на клиентских потоках, которые ждут подключения. Не совсем понятная часть - кто это делает и почему.

Догадка, что Tomcat сам это делает, потому что клиентские потоки слишком долго висят. Если нитки висят на getConnection(), это может быть связано с утечкой соединения и исчерпанием пула. Мы видим выше, как вы приобретаете Connections. Вы бдительно следите за тем, чтобы они были надежно close() ed в блоках finally?

Вы можете попытаться установить checkoutTimeout, например.

cpds.setCheckoutTimeout(5000); // 5 secs 

На самом деле это не решит проблему, если подвеска Connection висит. Но вместо проблемы, вызванной таинственными прерываниями, вместо этого вы увидите c3p0 TimeoutExceptions. Это будет проверять, что проблема долго зависает при проверке, хотя это, скорее всего, связано с исчерпанием пула, либо из-за утечки соединения (отсутствующие звонки на close()), либо просто из значения maxPoolSize для вашего груза.

Если есть утечка соединения, см. unreturnedConnectionTimeout и debugUnreturnedConnectionStackTraces для получения справки. См. Также "Configuring to Debug and Workaround Broken Client Applications"

+0

Я заметил более старую версию и обновил ее. вопрос остался. беря ваш совет, я установил setCheckoutTimeout (500) и получил: java.sql.SQLException: попытка клиента проверить, что соединение истекает. исключение. Бассейн исчерпан очень быстро, я догадался, что это может быть проблемой. – svarog

+0

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

+0

('unreturnedConnectionTimeout' и' debugUnreturnedConnectionStackTraces' очень и очень полезны для поиска Утечки соединения.) –

Смежные вопросы