Tomcat connection pool issue- Cannot call a method on closed connection - java

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.

Related

Closing conection from pool in runtime oracle-data-source

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>

c3p0 reconnect after network outage

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

Spring JDBC connections left open

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.

Tomcat JDBC Conencton Pool + MySQL gives "Broken pipe" problems, even with connection validation

I'm fighting with configuring Tomcat JDBC Connection Pool to achieve reliability. Current issue is that in test environment I have such scanerio in webapp:
day 1: everything works fine
day 2: webapp cannot comunicate with MySQL for several hours, lot of "Broken pipe" in logs
day 3: suprisingly, everything works fine again (without ingerention or restart)
I have configured validationInterval, validationQuery, validationTimeout. This is my data source config:
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="username" value="${dbUser}" />
<property name="password" value="${dbPass}" />
<property name="url" value="${dbUrl}" />
<property name="defaultAutoCommit" value="false" />
<property name="defaultTransactionIsolation">
<util:constant static-field="java.sql.Connection.TRANSACTION_SERIALIZABLE" />
</property>
<property name="maxActive" value="300" />
<property name="maxIdle" value="25" />
<property name="initialSize" value="5" />
<property name="validationInterval" value="5000" />
<property name="validationQuery" value="SELECT 1"/>
<property name="validationQueryTimeout" value="3" />
<property name="minIdle" value="5" />
<property name="initSQL" value="SET time_zone = '+00:00';" />
</bean>
I don't have autoReconnect=true parameter in connection URL, only UTF8 encoding.
The exact error is:
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:
The last packet successfully received from the server was 38,700,615
milliseconds ago. The last packet sent successfully to the server was
38,700,615 milliseconds ago. is longer than the server configured
value of 'wait_timeout'. You should consider either expiring and/or
testing connection validity before use in your application, increasing
the server configured values for client timeouts, or using the
Connector/J connection property 'autoReconnect=true' to avoid this
problem.
Caused by: java.net.SocketException: Broken pipe
We had some similar problems with one of our applications and after a lot of digging we added the following properties that solved all our connection problems:
maxAge="180000"
testOnBorrow="true"
testWhileIdle="true"
validationInterval="0" //forces the connection pool to validate each time a connection is given to the application
You need to set 'testOnBorrow' to 'true', and probably 'maxAge' to less than the server's configured 'wait_timeout', as hinted in the message.

Max User Connection issue with Hibernate and Java [duplicate]

This question already has an answer here:
User root already has more than 'max_user_connections' active connections in Hibernate
(1 answer)
Closed 3 years ago.
I am using following code for database connection with Hibernate and Java specified in my applicationcontext file,
<bean id="DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/database?useUnicode=true&characterEncoding=UTF-8" />
<property name="user" value="admin" />
<property name="password" value="pass" />
<property name="maxPoolSize" value="10" />
<property name="maxStatements" value="10" />
<property name="minPoolSize" value="5" />
<property name="initialPoolSize" value="10" />
<property name="maxIdleTime" value="120" />
<property name="numHelperThreads" value="1" />
<property name="preferredTestQuery" value="SELECT 1" />
</bean>
on the server after sometime it gives following error
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask run
WARNING:
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask#198c333 --
Acquisition Attempt Failed!!! Clearing pending acquires. While trying
to acquire a needed new resource, we failed to succeed more than the
maximum number of allowed acquisition attempts (30).
Last acquisition attempt exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: User admin already has more than 'max_user_connections' active connections
can anyone let me know where I m going wrong
It looks like you have a configuration problem with your database. It's likely that your database couldn't let to the same user 10 simultanious connections. Maybe you could try to reduce maxPoolSize and minPoolSize to 1 so you can see your real problem.(Since the exception that you see is just the last exception given)
Take a loot at these urls:
How To Configure DBCP Connection Pool In Hibernate
How To Configure The C3P0 Connection Pool In Hibernate
Hope it helps.

Categories

Resources