an issue occured when database restart with C3p0 configuration - java

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.

Related

SQLException: I/O Error: Read timed out

I have a Java Spring application connecting to a SQL Server database.
The connection settings are:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="net.sourceforge.jtds.jdbc.Driver" />
<property name="jdbcUrl"
value="jdbc:jtds:sqlserver://${db.host}:1433/TestDB" />
<property name="user" value="${db.user}" />
<property name="password" value="${db.pass}" />
<!-- these are connection pool properties for C3P0 -->
<property name="minPoolSize" value="10" />
<property name="maxPoolSize" value="100" />
<property name="acquireIncrement" value="5"/>
<property name="maxIdleTime" value="30000" />
</bean>
everything works fine but sometimes I got the following error:
Could not open JDBC Connection for the transaction; nested exception is java.sql.SQLException: I/O Error: Read timed out
I have searched a lot but can't find any clue, any idea or help?
I'm using
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
in my spring-config xml to get my sqlSession, and in the DAO I use:
#Autowired
SqlSession sqlSession;
and then I execute the queries I want. Is it possible that because the connection is not closed that this error exists?
In my case connections were getting dropped when the nightly db backup job triggered. I'm using jtds/sql-server as well. Here is what I did to fix it:
Create/setup a health-check cron job that executes a simple query from within your application, like a short select from. Call it every 10 minutes or so and log the result. It will give you some feedback about when and why this is happening.
Reduce the idle time parameter (maxIdleTime) in your configuration so that old connections get automatically discarded.
Keep in mind that if you don't change the maxIdleTime and you keep multiple connections open, some of them may remain in a bad state even if you are using the health-check function. Quoting from c3p0 documentation:
By default, pools will never expire Connections. If you wish Connections to be expired over time in order to maintain "freshness", set maxIdleTime and/or maxConnectionAge. maxIdleTime defines how many seconds a Connection should be permitted to go unused before being culled from the pool. maxConnectionAge forces the pool to cull any Connections that were acquired from the database more than the set number of seconds in the past.
Another way to setup a health-check call is by using the idleConnectionTestPeriod parameter. Also check this answer which can give you more ideas on how to set it up.

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.

tomcat jdbc pool max active not working?

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.

Hibernate and mysql timeout issue

I have been having trouble with Hibernate and Mysql timeout error.I am also using properties of c3p0(connection provider). After my Hibernate/MySQL have been running after 8 hours(which is default timeout value in Mysql), I have the exception. But it doesn't help.
property for auto reconnect also not working.
Here is my Hibernate Configuration:
<property name="connection_provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
**<property name="connection.autoReconnect"> true</property>
<property name="connection.autoReconnectForPools">true</property>**
<property name="connection.is-connection-validation-required">true</property>
<property name="c3p0.validate">true</property>
<property name="current_session_context_class">thread</property>
<property name="cache.use_query_cache">false</property>
<property name="cache.use_second_level_cache">false</property>
<property name="c3p0.idle_test_period">20</property>
<property name="c3p0.timeout">40</property>
<property name="c3p0.max_size">100</property>
<property name="c3p0.min_size">1</property>
<property name="c3p0.acquireRetryAttempts">10</property>
<property name="c3p0.maxPoolSize">100</property>
<property name="c3p0.maxIdleTime">300</property>
<property name="c3p0.maxStatements">50</property>
<property name="c3p0.minPoolSize">10</property>
<property name="c3p0.preferredTestQuery">select 1;</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/doqeap</property>
<property name="connection.user">root</property>
<property name="connection.password">*******</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.jdbc.batch_size">0</property>
<mapping></mapping>
please help me to sort out this problem.
Thanks
If the Connection timeout is the issue, then Connection testing should eliminate, wither via tests on checkout (reliable but imposes a client visible performance cost) or tests on checking + idle tests.
Looking at you config params, it looks like you mean to set tests on checkouts and idle tests. I'd expect that c3p0 would eliminate timed out Exceptions before your app saw them. If that hasn't happened, it'd be interesting to see two things: 1) c3p0's config, which gets logged at INFO when the pool is initialized -- is c3p0, through the hibernate layer, seeing the configuration you intend? 2) the Exception that your app receives when it encounters the stale Connections.
Good luck!

Categories