Settings for ComboPooledDataSource with JDBCTemplate - c3p0

For accessing DB I have created datasource using com.mchange.v2.c3p0.ComboPooledDataSource with following properties
`
<property name="initialPoolSize" value="5" />
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="idleConnectionTestPeriod" value="200" />
<property name="acquireIncrement" value="1" />
<property name="maxStatements" value="25" />
<property name="numHelperThreads" value="3" />`
My dao class extends JDBCDaoSupport and above datasource is set into the JDBCDaoSupport which inturn provides JDBCTemplate for executing queries. I am not using any transaction manager.
I have two questions now:
How the transaction in managed? Does JDBCTemplate itself creates the transaction before insert ?
If database is not available, Initializing c3p0 pool goes into infinite wait..I suppose there should be some property which I can set as a timeout for initialization of pool.
I tried '
<property name="acquireRetryAttempts" value="1" />
but not sure if this the correct way of doing it.

I'm not sure if JDBCTemplate works with ComboPooledDataSource... I was trying to configure it with c3p0 but it was giving me warnings, the connections were not returned to the pool and new connections were created for each request. It just flooded my Mysql server (and my application with Acquisition Attempt, Too Many Connections Error)
Also I couldn't find anything on net regarding JDBCTemplate configuration except one tutorial on RoseIndia. following which produced those errors.
I would suggest using SessionFactory (or maybe you can prefer core jdbc PreparedStatement and Resultset) for your db transactions.
As far as Retry Attempts is concerned, I don't think c3p0 would go to infinite way by default configuration. You can use acquireRetryAttempts and acquireRetryDelay to set retry attempt time.
From the mchange site itself :
"When a c3p0 DataSource attempts and fails to acquire a Connection, it will retry up to acquireRetryAttempts times, with a delay of acquireRetryDelay between each attempt. If all attempts fail, any clients waiting for Connections from the DataSource will see an Exception, indicating that a Connection could not be acquired."
It would be better to go through the reference documentation from mchange and configure your c3p0 as per your needs.
mchange c3p0 reference

Related

Spring MVC & Hibernate stops working after 8 hours

The following xml config file stops working after 8 hours of inactivity with this Error:
ERROR: Already closed.
25-may-2017 8:45:23 org.apache.catalina.core.StandardWrapperValve invoke
Servlet.service() for servlet [dispatcher] in the context with path [/system] threw exception [Request processing failed; nested exception is org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is org.hibernate.TransactionException: JDBC begin transaction failed: ] with root cause:
java.net.SocketException: **Software caused connection abort: recv failed**
Below is the Configuration file:
<context:component-scan base-package="es.company.system.persistence" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="es.mypackage.model"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="connection.url" value="jdbc:mysql://localhost:3306/system" />
<property name="connection.username" value="???" />
<property name="connection.password" value="???" />
<property name="hibernate.c3p0.min_size" value="5" />
<property name="hibernate.c3p0.max_size" value="20" />
<property name="hibernate.c3p0.timeout" value="1800"/>
<property name="hibernate.c3p0.max_statements" value="50" />
<property name="hibernate.c3p0.testConnectionOnCheckout" value="true" />
<property name="hibernate.c3p0.privilegeSpawnedThreads" value="true" />
<property name="hibernate.c3p0.contextClassLoaderSource" value="library" />
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<tx:annotation-driven transaction-manager="transactionManager" />
I'm currently using Spring MVC 4.3.8 and Hibernate 4.1.9. with C3P0 conections pool for MySQL. I thought with C3P0 this would be solved, but it's not.
Anyone knows what's wrong?
Thanks!!!
Software caused connection abort: recv failed --
This usually means that there was a network error, such as a TCP timeout.
also set timeout param with default = 0 for hibernate.c3p0.timeout
hibernate.c3p0.timeout – When an idle connection is removed from the
pool (in second). Hibernate default: 0, never expire.
set autoReconnect , hibernate.c3p0.autoReconnect = true or as url connection param : jdbc:mysql://localhost:3306/test?autoReconnect=true
Add < property name="hibernate.c3p0.preferredTestQuery">SELECT 1</property>
and check it log that c3p0 execute it(if not add real select count(1) from real table with limit 1). Also check your network timeout
I have experienced this issues some time google cloud sql where the SQL server breaks all the connection after idle time out of 10 hrs. But in the application we still have the sessionFactory instance and can create sessions but when you actually fire a db query it fails with broken connection exception.
None of the below attempts worked.
1. auto reconnect set in connection url
2. auto reconnect, timeout, validation properties in xml file.
3. Wrote a polling service to make a jdbc call to keep the connection active for every 8 hrs (<10 hrs idle time out period)
4. Closed and opened new sessionFactory for every db operation.
Finally i have created a polling service which will shutdown the sessiongFactory and create a new one.
NOTE: Calling close method on sessionFactory object is not sufficient. You need to explicit set it to null;
This may be a workaround but it saved me from day restart of the application.
I was not using spring just rest service with hibernate.

java.sql.SQLException: Already closed

We have a webapp running in production on tomcat with a MySQL back-end. All was fine for sometime, then suddenly we started getting this exception java.sql.SQLException: Already closed.
The entire stack trace is:
DEBUG [org.springframework.jdbc.datasource.DataSourceUtils] Fetching JDBC Connection from DataSource
DEBUG [org.springframework.jdbc.datasource.DataSourceUtils] Returning JDBC Connection to DataSource
DEBUG [org.springframework.jdbc.datasource.DataSourceUtils] Could not close JDBC Connection
java.sql.SQLException: Already closed.
at org.apache.commons.dbcp.PoolableConnection.close(PoolableConnection.java:114)
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.close(PoolingDataSource.java:191)
at org.springframework.jdbc.datasource.DataSourceUtils.doReleaseConnection(DataSourceUtils.java:333)
at org.springframework.jdbc.datasource.DataSourceUtils.releaseConnection(DataSourceUtils.java:294)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:405)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:428)
at com.nokia.analytics.aws.aggregate.service.importer.DBInsert.truncateTable(DBInsert.java:135)
at com.blah.analytics.aggregate.service.importer.AggregateCollector.pullAndInsert(AggregateCollector.java:85)
at com.blah.analytics.aggregate.service.importer.AggregateCollector.call(AggregateCollector.java:96)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1146)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:679)
We are using org.apache.commons.dbcp.BasicDataSource as our datasource. I searched quite a bit but to no avail.
It doesn't occur always and hence is very hard to reproduce. It seems a problem with db connection pooling. Somewhere it was suggested to set this param as negative. Currently we are not changing of those parameters (all have default vals).
What approach should we follow to avoid it?
EDIT:
The relevant code is in (DBInsert.java)
133: String sql = "DELETE FROM "+tableName;
134: logger.debug(sql);
135: this.jdbcTemplate.execute(sql);
(133-135 are line nos. which are specified in the exception)
My datasource config:
<bean id="bisToolDataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"
value="${url}/blah_db?verifyServerCertificate=false&useSSL=true&requireSSL=true" />
<property name="username" value="${uname}" />
<property name="password" value="${passwd}" />
</bean>
The cause of this problem is connection isn't used in a long time, add testOnBorrow and validationQuery property to your datasource configuration then your application will work fine.
Good luck:)
As user NobodyElse pointed out, the problem was related to connection pooling. I was using org.apache.commons.dbcp.BasicDataSource as datasource. The nature of the application is such that there is spurt of connections at some fixed time in the day and no connections at all for the entire day. So due to this connections in the pool were getting stale and when next day application tried to connect to DB, we were getting this exception.
There are basically two solutions to this:
The one pointed out by NobodyElse, that is to use testOnBorrow; details can be found here
The other solution (which I employed for our app) is to turn off pooling completely. Note do this only when the application is not DB intensive (which was true in our case). So I switched to org.springframework.jdbc.datasource.DriverManagerDataSource. The config for which it seems to be working fine is:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"
value="${url}/blah_db?verifyServerCertificate=false&useSSL=true&requireSSL=true" />
<property name="username" value="${uname}" />
<property name="password" value="${passwd}" />
</bean>

Hibernate, c3p0, and Mysql, spring

Many related issues are there at stack overflow but still i am putting this because still i haven't clear solution and exact reason for my problem.
I hope here i get complete solution of my problem and help full for All
I am using c3p0, MySQL, hibernate(J PA) and spring in my application.
Listing of main jar files i am using in my application is:
c3p0-0.9.2.jar
mchange-commons-java-0.2.3.3.jar
hibernate-commons-annotations-3.0.0.ga.jar
hibernate-entity manager.jar
hibernate-tools.jar
hibernate-validator-4.0.2.GA.jar
hibernate3.jar
mysql-connector-java-5.1.13-bin.jar
c3p0 settings in my persistent.XML is like this:
<property name="hibernate.c3p0.timeout" value="300"/>
<property name="hibernate.c3p0.max_statements" value="50"/>
<property name="hibernate.c3p0.idle_test_period" value="300"/>
Here that somewhere i read that hibernate.c3p0.idle_test_period must
not be higher of the hibernate.c3p0.timeout. In my case both are equal.
Is i need to change anything ?
how can i solve this problem ?
Server works fine for some hours(may be till 8 hours not exactly) and gives following error. error log is:
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:
Communications link failure
The last packet successfully received from the server was 35,019,246 milliseconds
ago. The last packet sent successfully to the server was 0 milliseconds ago.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1118)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3055)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2941)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3489)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1959)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2113)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2568)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2113)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2275)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery
(NewProxyPreparedStatement.java:116)
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:186)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1787)
at org.hibernate.loader.Loader.doQuery(Loader.java:674)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
at org.hibernate.loader.Loader.doList(Loader.java:2220)
... 39 more
Caused by: java.io.EOFException: Can not read response from server.
Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2502)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2952)
... 52 more
... 39 more
Caused by: java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3302)
... 50 more
Here I am showing the snapshot of my persistent.xml:-
<properties>
<property name="hibernate.connection.username" value="****"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.password" value="***************"/>
<property name="hibernate.connection.url" value="jdbc:mysql://xxx.xxx.x.xx:3306/projectname?autoReconnect=true"/>
<!--Connection Pooling c3p0 configuration-->
<!--Minimum number of JDBC connections in the pool. Hibernate default: 1-->
<property name="hibernate.c3p0.min_size" value="5"/>
<!--Maximum number of JDBC connections in the pool. Hibernate default: 100-->
<property name="hibernate.c3p0.max_size" value="20"/>
<!--When an idle connection is removed from the pool (in second). Hibernate default: 0, never expire.-->
<property name="hibernate.c3p0.timeout" value="300"/>
<!--Number of prepared statements will be cached. Increase performance. Hibernate default: 0 , caching is disable.-->
<property name="hibernate.c3p0.max_statements" value="50"/>
<!--idle time in seconds before a connection is automatically validated. Hibernate default: 0-->
<property name="hibernate.c3p0.idle_test_period" value="300"/>
</properties>
I use singleton object of connection class in my application.
public static void createConnection()
{
if (em != null)
{
Connection.em.clear();
}
if (em == null) {
new Connection();
}
Thanks in advance. Hope i will get my solution.
--Om--
A singleton Connection object is a bad idea (at least it is in any concurrent, multi-client application). It is certainly inconsistent with a Connection pool, the philosophy of which is that Connections should be acquired from the pool when they are needed and returned to the pool [by calling close()] as soon as a unit of work is done.
Right now, your singleton Connection will timeout, and there is nothing c3p0 can do about it. Connection pools manage and test Connections when they are checked into the pool. When they are checked out, the pool tries to stay out of the way and not interfere with the client.
==> All of that said, it's unclear what your "Connection" class is here. It looks like it is not a java.sql.Connection after all, because you have a static field called "em" in Connection. So it is hard to interpret what's going on.
Broadly, you want a single c3p0 DataSource, and to acquire Connections as-needed and to close() them as promptly as possible.
To prevent Connection timeouts like you are seeing, the best approach a Connection testing regime. The easiest approach would be to set...
hibernate.c3p0.validate=true
hibernate.c3p0.preferredTestQuery=SELECT 1
Once you have that working, you can enhance the performance a bit by using testConnectionOnCheckin and idleConnectionTestPeriod (or hibernate.c3p0.idle_test_period). See http://www.mchange.com/projects/c3p0/#configuring_connection_testing
It makes no sense to have your idleConnectionTestPeriod (hibernate.c3p0.idle_test_period) and maxIdleTime (hibernate.c3p0.timeout) be the same. Idle connections will never be tested; they'll expire before they get the chance. idleConnectionTestPeriod (hibernate.c3p0.idle_test_period), if you set it at all, should be much shorter than maxIdleTime (hibernate.c3p0.timeout).
Good luck!
As this is the first hit in Google I'll share what brought me the solution to this problem showing up on our production servers: http://drglennn.blogspot.nl/2009/05/javasqlsqlexception-communication-link.html
What made this a nasty bug is that the application will work by ommitting:
<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
in your persistence-unit config but it will not use the C3P0 Connection Pool and will therefore generate connection failures.
Caused by: CommunicationsException: Communications link failure
That exception means Database isn't reachable.
Since you are able to connect to Database I guess issue might be
1) DB server is down at that time
2) DB server has run out of connections.
Try connecting to Database using some other tool, MySQL Workbench or from console, at the time you get this exception
You should rater configure you a datasource. Otherwise there is much trouble with the interaction of spring an c3o0.
<bean id="dataSource_core" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${hibernate.connection.driver_class}" />
<property name="jdbcUrl" value="${hibernate.connection.url}" />
<property name="user" value="${hibernate.connection.username}" />
<property name="password" value="${hibernate.connection.password}" />
<property name="minPoolSize" value="${hibernate.connection.minPoolSize}" />
<property name="maxPoolSize" value="${hibernate.connection.maxPoolSize}" />
<property name="maxIdleTime" value="${hibernate.connection.maxIdleTime}" />
<property name="maxStatements" value="${hibernate.connection.maxStmts}" />
<property name="testConnectionOnCheckout" value="${hibernate.connection.testCo}" />
<property name="testConnectionOnCheckin" value="${hibernate.connection.testCo}" />
<property name="preferredTestQuery" value="${hibernate.connection.testSQL}" />
<property name="idleConnectionTestPeriod" value="${hibernate.connection.testPeriod}" />
</bean>

spring + hibernate + data base connection pooling and high availability

I'm trying to configure my web application like this:
1 tomcat server
2 mysql data bases in master/ master replication for failover purpose.
I also succeded to set up a pooled connexion using c3p0, thus avoiding to open a new connexion for each request(when no failover is involved)
I would like to use the failover support porvided by the jdbc connector in order to route request to the second database when the first one is unavailabe. Thus i'm using the fail over capability of the jdbc driver, simply by providing extra configuration parameters.
For the moment, when one server is unvailable, the requst are routed to the second available server. However, i'm facing a problem with a new opened connexion on the database for each request.
It seems that combaining connexion pooling and jdbc failover dosen't work toogther ?
Please advice, also regarding configuration parameters
<bean id="mydataSource" 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,myOtherServer:3306/zeus?autoCommit=true&autoReconnect=true&autoReconnectForPools=true&failOverReadOnly=false"/>
<property name="user" value="root" />
<property name="password" value="root" />
<!-- these are C3P0 properties -->
<!-- property name="acquireIncrement" value="${acquireIncrement}" /_-->
<property name="minPoolSize" value="6" />
<property name="maxPoolSize" value="10" />
<property name="maxIdleTime" value="100" />
</bean>

getting java.io.EOFException when trying to insert data in mysql from spring mvc app

I am trying to submit data from spring mvc app to mysql . sometime i get the following error
org.springframework.dao.DataAccessResourceFailureException: StatementCallback; SQL [insert into networkwithusdb(company,firstname,lastname,email,address1,address2,city,state,zipcode,currentemployer,currentjobtitle,primarycareerarea,secondarycareerarea) values('HCA North Texas','dd','af','bhanukiran#imomentous.info','','','','KS','','','','Facilities','Facilities')]; Communications link failure due to underlying exception:
** BEGIN NESTED EXCEPTION **
java.io.EOFException
STACKTRACE:
java.io.EOFException
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1963)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2375)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2874)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1623)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1715)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3243)
at com.mysql.jdbc.Statement.executeUpdate(Statement.java:1343)
at com.mysql.jdbc.Statement.executeUpdate(Statement.java:1260)
at org.apache.commons.dbcp.DelegatingStatement.executeUpdate(DelegatingStatement.java:228)
at org.springframework.jdbc.core.JdbcTemplate$1UpdateStatementCallback.doInStatement(JdbcTemplate.java:508)
at org.springframework.jdbc.core.JdbcTemplate$1UpdateStatementCallback.doInStatement(JdbcTemplate.java:1)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:395)
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:518)
at com.imomentous.hcanorthtexas.service.DatabaseService.insertNetworkData(DatabaseService.java:58)
at com.imomentous.hcanorthtexas.controller.NetworkWithUsController.processNetworkWithUSForm(NetworkWithUsController.java:62)
[... snip ...]
** END NESTED EXCEPTION **
only few times i get this exception.
following are my configuration file:
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName">
<value>${database.driver}</value>
</property>
<property name="url">
<value>${database.url}</value>
</property>
<property name="username">
<value>${database.username}</value>
</property>
<property name="password">
<value>${database.password}</value>
</property>
<property name="maxActive" value="5" />
<property name="initialSize" value="3" />
<property name="validationQuery" value="SELECT 5 FROM DUAL" />
<property name="testOnBorrow" value="true" />
</bean>
and i am using the properties as:
database.driver =com.mysql.jdbc.Driver
database.url=jdbc:mysql://localhost:3306/XXXmobiledb
database.username=XXXX
database.password=XXXX
i am using:mysql-connector-java-5.0.5.jar
mysql server 5 .
sometimes database connection works properly and i get the result.
but sometimes it generates the error.
what might be the problem? If any have some idea please tell..thanks
The fact is that MySQL will disconnect the opened socket after a given time. You are advised to use a connection pool (such as c3p0).
See this post on the MySQL forum - http://forums.mysql.com/read.php?39,143312,180718#msg-180718. This should resolve it for you.
It might happen after a long time of inactivity add validation Query to your dataSource bean:
<property name="validationQuery">
<value>Select 1</value>
</property>
To avoid MySQL from disconnecting your session after a given idle time, you can use Spring OpenSessionInViewFilter or Interceptor to handle session.
This will require additional session filter settings in your web.xml file. You can mimic this post.