tomcat jdbc pool max active not working? - java

I use spring jdbc template for app.. and deploy it in tomcat.. I want to use connection pool with tomcat jdbc. My connection configuration is
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3310/mydb" />
<property name="username" value="***" />
<property name="password" value="***" />
<property name="maxWait" value="10000" />
<property name="removeAbandonedTimeout" value="60" />
<property name="removeAbandoned" value="true" />
<property name="logAbandoned" value="false" />
<property name="initialSize" value="10" />
<property name="maxActive" value="100" />
<property name="minIdle" value="10" />
</bean>
I don't know how, but when I run some test, and check the max thread in mysql, it show that the active thread is more than the maxActive configured in the configuration. So, why the maxActive in the configuration not working? And how to make it work? For example, the maxActive is 100 but when I check in mysql, the active thread is more than the maxActive.

maxActive (int) The maximum number of active connections that can be
allocated from this pool at the same time. The default value is 100
maxIdle (int) The maximum number of connections that should be kept in
the pool at all times. Default value is maxActive:100 Idle connections
are checked periodically (if enabled) and connections that been idle
for longer than minEvictableIdleTimeMillis will be released. (also see
testWhileIdle)
So i should recommend you to use maxIdle too, example:
<property name="maxIdle" value="100">
But maybe there is a problem, if you could show the code of your connection management, it would be helpful.
Here is an interesting link of a connection problem with declarative and programmatic transaction management with Spring: Connection pool problem with Spring and programmatic transaction management

I got the same problem with you and my tomcat version is tomcat 9.
Here is my solution: you should set maxTotal value 100 instead of maxActive.
maxTotal: Maximum number of database connections in pool. Make sure you configure your mysqld max_connections large enough to handle all of your db connections. Set to -1 for no limit.
FROM http://tomcat.apache.org/tomcat-9.0-doc/jndi-datasource-examples-howto.html.

Related

Spring Throws "ERROR SqlExceptionHelper: Already closed" after timeout

I have a spring application hosted on to the server (Tomcat 8.5). It goes idle if no one uses it. I already knew that timeout will occur if the DB is in idle state for 8 hours (Default timeout of MySQL). As mentioned in Spring Autoreconnect and Connection lost overnight post i have tried the solution available here.I have tried configuring application.properties but that doesn't bring any solution to the problem.
(PS:I'm not changing anything other than application.properties in my Spring Application).
Well if this
spring.datasource.testWhileIdle = true
spring.datasource.timeBetweenEvictionRunsMillis = 60000
spring.datasource.validationQuery = SELECT 1
or this
spring.datasource.testOnBorrow=true
spring.datasource.validationQuery=SELECT 1
didnt work maybe try this
Post SpringBoot 1.4 names have changed
They have defined new specific namespaces for the four connections pools spring supports: tomcat, hikari, dbcp, dbcp2.
spring.datasource.tomcat.testOnBorrow=true
spring.datasource.tomcat.validationQuery=SELECT 1
If problem doesn't solve even after including properties as in application.properties, Then problem will be solved when including testOnBorrow,validationQuery in application-context.xml located in src/main/resources
<bean name="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${database.driver.classname}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
<property name="initialSize" value="2"/>
<property name="maxActive" value="50"/>
<property name="maxIdle" value="5"/>
<property name="maxWait" value="-1"/>
<property name="removeAbandoned" value="true"/>
<property name="removeAbandonedTimeout" value="600"/>
<property name="logAbandoned" value="true"/>
<property name="testOnBorrow" value="true" />
<property name="validationQuery" value="SELECT 1" />
</bean>
The solution is to validate connection thread when it is borrowed from thread pool by enabling testOnBorrow and providing validationQuery.

c3p0 inactive connection not being culled from connection pool after max wait time

I have an existing app that utilizes Spring 3.0.3, Hibernate 3.6.0 and an Oracle DB.
I've got it set up and running c3p0 but I noticed something strange that I can't really figure out.
This is my Spring set up
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${xxgglom.driver}" />
<property name="jdbcUrl" value="${url}" />
<property name="user" value="${username}" />
<property name="password" value="${password}" />
<property name="minPoolSize" value='5' />
<property name="maxPoolSize" value="40" />
<property name="maxIdleTime" value="240" />
<property name="maxIdleTimeExcessConnections" value="180" />
<property name="maxStatements" value="50" />
<property name="testConnectionOnCheckin" value="true" />
<property name="testConnectionOnCheckout" value="false" />
<property name="idleConnectionTestPeriod" value="300" />
I check the database v$session and I see it creates the 5 connections in the pool. I'll start using the app and it will increase the pool size when needed. So I can tell C3P0 is working from checking the logs. The one issue I'm having is. There are these inactive connections, that are pass the maxIdleTime.
I check their alive times and they're way pass the 240 seconds. I check the database again and they all show inactive but when I look in the logs tell me this.
trace com.mchange.v2.resourcepool.BasicResourcePool#282fafdd [managed: 5, unused: 4, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection#5f9f7637)
I'm not sure what's going on exactly but after awhile these idle connections start piling up, and they don't seem to be getting culled from the connection pool. Any suggestions on what to do?
maxIdleTime doesn't guarantee that Connections will be culled at any particular time. As long as each Connection is used at least once every 4 minutes under your config, they won't be culled. If you want to put an unconditional limit on Connections' live-time (I don't know why you would), you can use maxConnectionAge.

c3p0 - maxIdleTime configuration

I have a basic c3p0 configuration as below. What I am asking is when there is no traffic on the application (connections stay idle), could c3p0 shrink the pool when maxIdleTime is reached for each connection since min and max connection numbers are the same?
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/>
<property name="jdbcUrl" value="#[jdbc.url]"/>
<property name="user" value="#[jdbc.username]"/>
<property name="password" ref="DbPassword"/>
<property name="minPoolSize" value=25/>
<property name="maxPoolSize" value=25/>
<property name="acquireIncrement" value= 1/>
<property name="idleConnectionTestPeriod" value="100"/>
<property name="maxIdleTime" value="120"/>
<property name="preferredTestQuery" value ="select 1 from dual"/>
maxIdleTimeExcessConnections is about minimizing the number of Connections held by c3p0 pools when the pool is not under load. By default, c3p0 pools grow under load, but only shrink if Connections fail a Connection test or are expired away via the parameters described above. Some users want their pools to quickly release unnecessary Connections after a spike in usage that forces a large pool size. You can achieve this by setting maxIdleTimeExcessConnections to a value much shorter than maxIdleTime, forcing Connections beyond your set minimum size to be released if they sit idle for more than a short period of time.

an issue occured when database restart with C3p0 configuration

My application has a timer that execute every 60 seconds. Each execution will access the oracle database with C3p0 connection pool. The existing configuration for C3p0 of my application is as following(there are other tasks to access db):
*<property name="acquireIncrement" value="1"/>
<property name="initialPoolSize" value="10"/>
<property name="maxPoolSize" value="25"/>
<property name="minPoolSize" value="10"/>
<property name="maxStatements" value="250"/>
<property name="maxStatementsPerConnection" value="10"/>
<property name="numHelperThreads" value="6"/>
<property name="checkoutTimeout" value="30000"/>
<property name="maxIdleTimeExcessConnections" value="1800"/>
<property name="idleConnectionTestPeriod" value="900"/>
<property name="preferredTestQuery" value="SELECT 'x' FROM DUAL"/>*
Now I got an issue that when database shutdown, the timer will throw SQLexcetion for bad connection for each execution, but when the database recover, it keep throwing SQLExcetion for bad connection.
I think that the reason should be when application startup, 10 connection will be established, and timer occupy one of them, when database shutdown, the connection broken, and then database recover, the timer still uses the broken connection.
But I am not sure whether my assumption is correct, the timer will use single connection for its each execution even it has already broken?
If my thinking is correct, I want to reduce idleConnectionTestPeriod to less than 60 seconds that is the time intenal of timer to fix this issue.
Could you guide me on this problem? Thank you.

Can't open connection

I develop an applivation with very load(request).
I used following technologies in my appliation:
Jpa/Hibernate as persistense layer
Spring and Spring Dao
C3p0 as connection pooling
my problem is : I run my application , when number of request increase, throw exception in
persistense layer that"Cannt open connection"
I increase oracle max session but my problem not solve
I indept in C3p0 document and test its options but my problem not solve.
Thank you for your attention
You increased max sessions on Oracle, but you didn't increase the max size of your connection pool. The exception is telling you that your pool is exhausted. Either find what's holding connections open and get them released sooner, or increase the number of max active connections in the pool.
Is it possible for you to post the Spring configuration for your DataSource. I would expect something like:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/>
<property name="jdbcUrl" value="${jdbc.connection.url}"/>
<property name="user" value="${jdbc.connection.username}"/>
<property name="password" value="${jdbc.connection.password}"/>
<property name="initialPoolSize" value="5"/>
<property name="minPoolSize" value="5"/>
<property name="maxPoolSize" value="100"/>
</bean>
With another bean configured where the dataSource is passed by reference:
<bean id="mySampleDao" class="com.example.dao.MySampleDao">
<property name="dataSource" ref="dataSource" />
</bean>
Is this what you have?
What version of Oracle are you using?

Categories