I'm using the following bean to connect to the DB through JDBC:
<bean id="databaseds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="removeAbandoned" value="true"/>
<property name="initialSize" value="1" />
<property name="maxActive" value="2" />
<property name="maxIdle" value="0" />
<property name="minEvictableIdleTimeMillis" value="120000" />
</bean>
Using quartz a new class is constructed which takes advantage of Spring JDBC to run SQL statements. What I did notice is that most of the the JDBC connections are still hanging around hours after the quartz job ran and completed. Based on the bean I'm expecting to have NO idle sessions 2-3 minutes after the connection is not being used.
Am I missing anything? I don't want to keep more than 1-2 connections open to the database, the program is not doing any DB intensive work but does run every 30 minutes and if the connections are not reused or closed they pile up.
Related
I have soap webservice written in Spring 2.X and which connect to Teradata and return the result to client. To connect the data based I am using Tomcat JDBC Connection Pool as the DataSource.
In peak hour (9AM to 6PM) application get about 60k transactions requests. I observed some of the transactions goes in hung state and return response in 2-3 minutes . I suspect some transaction goes in wait status and once connection is available in pool then complete the transactions.
Below is the configuration for the DataSource.
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource"
destroy-method="close">
<property name="driverClassName" value="com.teradata.jdbc.TeraDriver"/>
<property name="url" >
<util:constant static-field=" _DB_HOST"/>
</property>
<property name="username">
<util:constant static-field=" DB_USER"/>
</property>
<property name="password">
<util:constant static-field=" DB_PWD"/>
</property>
<property name="initialSize" value="1" />
<property name="maxActive" value="50" />
<property name="minIdle" value="0" />
<property name="maxWait" value="-1" />
<property name="minEvictableIdleTimeMillis" value="1000" />
<property name="timeBetweenEvictionRunsMillis" value="1000" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
<qualifier value="txnMngr"/>
</bean>
// using JdbcTemplate to read the data from data base.
Here are my questions:
Is there any issue with above configuration based on the load which I mentioned for my application?
Is there any way I can monitor the DB connection pool uses?
My application is using Spring 2.5.x and deployed on Tomcat server. Some times, I get below error when my db connection is idle:
[TeraJDBC 14.00.00.13] [Error 1095] [SQLState HY000] Cannot call a
method on closed connection
Here is the datasource configuration
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource"
destroy-method="close">
<property name="driverClassName" value="com.teradata.jdbc.TeraDriver"/>
<property name="url" >
<util:constant static-field="_DB_HOST"/>
</property>
<property name="username">
<util:constant static-field="_DB_USER"/>
</property>
<property name="password">
<util:constant static-field="_DB_PWD"/>
</property>
<property name="initialSize" value="1" />
<property name="maxActive" value="50" />
</bean>
Is there any configuration I'm missing here?
While all connections used by Spring's JdbcTemplate are closed at the end of each transaction, Tomcat's JDBC Connection Pool never actually returns the real Connection's obtained by the driver. DataSource#getConnection always returns a proxy, such that Connection#close returns the connection to the pool instead of physically closing it.
Therefore, as explained in this answer, the connections are probably closed by the server. Therefore you need to configure the pool to validate the connections, as in the answer cited by Kayaman.
I suspect that your problem is not caused by connection issues, but server policy, so I would set up:
<property name="validationQuery" value="SELECT 66353343" />
<property name="testWhileIdle" value="true" />
<property name="timeBetweenEvictionRunsMillis" value="60000" />
in order to check every 60 seconds if the physical connections are up.
I have legacy web application. Witch uses jdbcTemplate to execute stored procedures from DB (Oracle), procedures located at packages. Problem is, when database developers compiles that packages im getting Expceptions sometihng like existing state of packages been changed (ora 4061). and they does that 1 or 2 times per week. Then i have to restart application to restart pool. app uses OracleDataSource. i can't change anything at that db but can change pool manager. so the question is. is it possible to close that connection? not just return to pool. and get new connection(from pool) if that Exception apears? thanks !!
people sugested to re-execute that stored procedure when that error apears. It doest worked.
<bean id="ds_name" class="oracle.jdbc.pool.OracleDataSource"
destroy-method="close">
<property name="connectionCachingEnabled" value="true" />
<property name="URL" value="****" />
<property name="user" value="user" />
<property name="password" value="pass" />
<property name="connectionCacheProperties">
<value>
MinLimit:1
MaxLimit:100
InitialLimit:1
ConnectionWaitTimeout:120
InactivityTimeout:180
ValidateConnection:true
</value>
</property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="ds_name" />
</bean>
The application connects to MS SQL server. It uses the c3p0 ComboPooledDataSource in Tomcat and Spring environment.
When the application loses database connection and gets it back few seconds later, the application recovers the connection and can continue querying the db quickly (as soon as the network is back).
But it the network outage is longer, the application needs more than 10 minutes to recover a db connection after network came back.
I see these logs when the db connection is back after 10 minutes:
[WARNING] Exception on close of inner statement.java.sql.SQLException: Invalid state, the Connection object is closed.
at net.sourceforge.jtds.jdbc.TdsCore.checkOpen(TdsCore.java:481)
[WARNING] [c3p0] A PooledConnection that has already signalled a Connection error is still in use!
[WARNING] [c3p0] Another error has occurred [ java.sql.SQLException: Invalid state, the Connection object is closed. ] which will not be reported to listeners!java.sql.SQLException: Invalid state, the Connection object is closed.
Here is the spring-config.xml configuration:
<bean id="CommonDataSource" abstract="true" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="net.sourceforge.jtds.jdbc.Driver" />
<property name="minPoolSize" value="${db.minPoolSize}" />
<property name="maxPoolSize" value="${db.maxPoolSize}" />
<property name="acquireRetryAttempts" value="0" />
<property name="checkoutTimeout" value="0" />
<property name="testConnectionOnCheckout" value="true" />
<property name="testConnectionOnCheckin" value="false" />
<property name="idleConnectionTestPeriod" value="10" />
<property name="preferredTestQuery" value="select 1" />
</bean>
I tried other configurations, with a non-zero checkoutTimeout, testConnectionOnCheckout=false and testConnectionOnCheckin=true, the recovery still is very long.
What is wrong with my configuration? I would like to recover the db connection as soon as network issues are fixed.
Many thanks for you help
EDIT with Hakari configuration as suggested by M. Deinum
Hi,
I tried with this Hakari configuration:
<bean id="CommonDataSource" abstract="true" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<property name="maximumPoolSize" value="${db.maxPoolSize}" />
<property name="connectionTestQuery" value="select 1"/>
<property name="allowPoolSuspension" value="true"/>
</bean>
But the behaviour is similar: I have to wait for 10-15 minutes before getting the database connection back.
Would you have any suggestion please?
The issue was not related to c3p0 nor HikariCP. I had to modify the jdbc url and add these properties:
loginTimeout=60;socketTimeout=60
Maybe only one is enough but I could do the job with both of these.
This link helps a lot http://jtds.sourceforge.net/faq.html
I am working on spring based application where I manage connection pool to manage connection between MySQL and Java application.
Connection pool configuration looks like this:
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" >
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.password}" />
<property name="initialSize" value="20" />
<property name="maxActive" value="100" />
<property name="maxIdle" value="50" />
<property name="minIdle" value="10" />
</bean>
Now my questions are:
1) I have two different applications having the same configuration, then how many connection pool will mysql maintain, it will one for all application having maxactive1=100 or it will based on per application. In my case 2* 100 = 200(maxactive).
2) what can be best maxactive value if i have 500 requests in 1 sec?
1) MySQL doesn't know about your connection pools. MySQL has own option for max allowed connections. And the number should be bigger than sum of connections required by all the connection pools. So in your case 2*100.
2) best maxactive value depends on multiple factors. 500 requsts per second if one request is processed 1 second requires 500 connections. But if the request processing time is 0.1 sec 50 connections would be enough.