5
respostas

ESTOURO MAXPOOLSIZE C3P0

Estou com problema quando estoura o máximo de conexões na minha aplicação. Eu fiz um monitoramento e verifiquei que quando um conexão fica disponível a aplicação volta a funcionar normalmente mas se os clientes fizerem requisições já com limite max de conexões abertas minha aplicação fica travada e começa a gerar vários erros.

Alguém tem uma solução de configuração do C3P0 para isso?

Caused by: org.hibernate.exception.GenericJDBCException: Could not open connection
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
    at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:235)
    at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.getConnection(LogicalConnectionImpl.java:171)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:67)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:162)
    at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1431)
    at org.hibernate.jpa.internal.TransactionImpl.begin(TransactionImpl.java:61)
    ... 61 more
Caused by: java.sql.SQLException: An attempt by a client to checkout a Connection has timed out.
    at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:118)
    at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:77)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:687)
    at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:140)
    at sun.reflect.GeneratedMethodAccessor40.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at net.bull.javamelody.JdbcWrapper$3.invoke(JdbcWrapper.java:811)
    at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:291)
    at com.sun.proxy.$Proxy14.getConnection(Unknown Source)
    at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:139)
    at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:380)
    at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:228)
    ... 66 more
Caused by: com.mchange.v2.resourcepool.TimeoutException: A client timed out while waiting to acquire a resource from com.mchange.v2.resourcepool.BasicResourcePool@a85f0f7 -- timeout at awaitAvailable()
    at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1416)
    at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:606)
    at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:526)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutAndMarkConnectionInUse(C3P0PooledConnectionPool.java:755)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:682)
5 respostas

Eu acho que a melhor solução é alterar o tamanho do pool.. seu teste ta stressando de um jeito que o pool não ta dando conta. Não acho que vale a pena aumentar configurações de timeouts e tal... Outra coisa importante, use a última versão da lib, sempre. Ainda mais essas que lidam com partes tão sensíveis da aplicação.

Bom dia Alberto,

Estou usando essa configuração no meu datasource do tomcat.

<Resource name="jdbc/Aplicacao" 
        auth="Container" 
        factory="org.apache.naming.factory.BeanFactory"
        type="com.mchange.v2.c3p0.ComboPooledDataSource"
        driverClass="com.mysql.jdbc.Driver" 
        jdbcUrl="jdbc:mysql://172.00.00.110:3306/teste?zeroDateTimeBehavior=convertToNull"
        user="teste"
        password="teste"
        initialPoolSize="3"
        minPoolSize="5"
            maxPoolSize="50"
            acquireIncrement="3" 
                   maxStatements="0"
            acquireRetryAttempts="30"
        acquireRetryDelay="1000"
        breakAfterAcquireFailure="false"
        maxIdleTime="180"
        maxConnectionAge="10"
        unreturnedConnectionTimeout="35" 
        debugUnreturnedConnectionStackTraces="true"
        checkoutTimeout="1000"
        idleConnectionTestPeriod="60"
        testConnectionOnCheckout="true"
        preferredTestQuery="SELECT 1"
        testConnectionOnCheckin="true"
            numHelperThreads="5"                
        />

Ontem após eu inserir a linha unreturnedConnectionTimeout="35" minha aplicação no monitoramento (estou utilizando o javaMelody) na parte "Conexões JDBC abertas" não parou mais após atingir o maxPoolSize. A aplicação continuo recebendo mais conexões conforme necessitava e não travo mais.

Mas hoje estou vendo no monitoramento tem atualmente 218 conexões abertas. O c3p0 não deveria matar as conexões que não estão utilizando mais e os numeros de conexões abertas não deveriam ir reduzindo?

Grato!

Eh que aí não eh o c3p0, e sim o pool do Tomcat.. de todo jeito, o padrão eh ir matando em.funcao do idletimeout sim.

O que eu devo configurar ou configurei errado que ele não esta matando as conexões?

Então, supostamente vc configurou => maxIdleTime

Você pode tentar trocar o pool e analisar o comportamento.. pq tem mais cara de comportamento errado do que erro seu.