0

I am using Apache Camel with Spring boot. I am using my spring boot app as jar without any server.

In app I am having a Camel-SQL consumer route with delay of 1000. This consumer then further calls other route which use splitter and parallel processing.

Through Jprofiler I have observed that my DB connection are not getting closed which are opened through consumer.

I also have dbcp2 settings in application.properties and using Oracle DB. I am observing this connection issue for the first time. Did anyone also faced the same issue at anytime? Or do I need to add any other configuration.

Any help will be appreciated.

gomzee
  • 103
  • 1
  • 9

1 Answers1

0

Here is one of my Oracle configurations:

<cm:property-placeholder id="server.placeholder" persistent-id="name.of.company.datasource">
    <cm:default-properties>
        <cm:property name="db.host" value="host"/>
        <cm:property name="db.port" value="1521"/>
        <cm:property name="db.instance" value="dbname"/>
        <cm:property name="db.user" value="user"/>
        <cm:property name="db.password" value="password"/>
        <cm:property name="driverClassName" value="oracle.jdbc.pool.OracleDataSource" />
        <cm:property name="validationQuery" value="SELECT 1 FROM DUAL" />
        <cm:property name="defaultReadOnly" value="false" />
        <cm:property name="defaultAutoCommit" value="true" />
        <cm:property name="maxActive" value="100" />
        <cm:property name="whenExhaustedAction" value="2" />
        <cm:property name="maxWait" value="-1" />
        <cm:property name="maxIdle" value="8" />
        <cm:property name="minIdle" value="1" />
        <cm:property name="testOnBorrow" value="true" />
        <cm:property name="testOnReturn" value="true" />
        <cm:property name="timeBetweenEvictionRunsMillis" value="-1" />
        <cm:property name="numTestsPerEvictionRun" value="3" />
        <cm:property name="minEvictableIdleTimeMillis" value="1800000" />
        <cm:property name="testWhileIdle" value="false" />
        <cm:property name="softMinEvictableIdleTimeMillis" value="-1" />
        <cm:property name="lifo" value="true" />
    </cm:default-properties>
</cm:property-placeholder>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  <property name="driverClassName" value= "${driverClassName}" />
  <property name="url" value="jdbc:oracle:thin:@${db.host}:${db.port}:${db.instance}" />
  <property name="username" value="${db.user}" />
  <property name="password" value="${db.password}" />
  <property name="maxIdle" value="1" />
</bean>

<bean id="connectionFactory" class="org.apache.commons.dbcp.DataSourceConnectionFactory">
  <argument ref="dataSource" />
</bean>

<bean id="connectionPool" class="org.apache.commons.pool.impl.GenericObjectPool" >
  <argument><null/></argument>
  <argument value="${maxActive}" />
  <argument value="${whenExhaustedAction}" />
  <argument value="${maxWait}" />
  <argument value="${maxIdle}" />
  <argument value="${minIdle}" />
  <argument value="${testOnBorrow}" />
  <argument value="${testOnReturn}" />
  <argument value="${timeBetweenEvictionRunsMillis}" />
  <argument value="${numTestsPerEvictionRun}" />
  <argument value="${minEvictableIdleTimeMillis}" />
  <argument value="${testWhileIdle}" />
  <argument value="${softMinEvictableIdleTimeMillis}" />
  <argument value="${lifo}" />
</bean>

<bean id="pooledConnectionFactory" class="org.apache.commons.dbcp.PoolableConnectionFactory" >
  <argument ref="connectionFactory" />
  <argument ref="connectionPool" />
  <argument><null/></argument>
  <argument value="${validationQuery}" />
  <argument value="${defaultReadOnly}" />
  <argument value="${defaultAutoCommit}" />
</bean>

<bean id="poolingDataSource" class="org.apache.commons.dbcp.PoolingDataSource" depends-on="pooledConnectionFactory">
  <argument ref="connectionPool" />
</bean>

<service interface="javax.sql.DataSource" ref="poolingDataSource"> 
    <service-properties>
        <entry key="osgi.jndi.service.name" value="jdbc/oracle/db"/>
        <entry key="datasource.name" value="jdbc/oracle/db" />
    </service-properties>
</service>

Maybe it will help you. I think DB connection just doesn't have time to go back to the pool between queries. You need to configure the connection timeout and similar parameters (idle params, minEvictableIdleTimeMillis, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun).

Alexey Yakunin
  • 1,743
  • 1
  • 19
  • 21
  • Hi Alexey, thank you for the reply. I have properties related to dbcp2 already in place. Problem is connection are not getting closed due to which new connection cannot be created. – gomzee Mar 19 '19 at 05:43
  • @gomzee, IMHO, the maxActive value was exceeded during the operation of the routes. This is because the connections do not have time to return to the pool. – Alexey Yakunin Mar 19 '19 at 08:56
  • Alexey, DB config is: spring.datasource.dbcp2.initial-size=30 spring.datasource.dbcp2.max-total=40 spring.datasource.dbcp2.pool-prepared-statements=true spring.datasource.dbcp2.max-idle=8 spring.datasource.dbcp2.min-dle=2 And my maxMessagesPerPoll=10. So for processing 396 records my program stops at 380 records always, after processing 380 records it cannot get DB connection. And through JProfiler I can see all active connections as memory leaks. – gomzee Mar 19 '19 at 15:55