Database Connections Aren't Closing - mysql

I'm using spring 3.0 (jdbcTemplate), Tomcat, MySQL and C3p0 to handle my database activities. I'm using both jdbctemplate and simplejdbctemplate which will take care of creating and closing connections, statements, resultsets etc. I'm using C3p0 for connection pooling however the connections are remaining open and eventually the app will run out of connections.
Here is the configuration of my data source:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close" >
<property name="driverClass" value="${jdbc.driverClassName}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="initialPoolSize" value="5"></property>
<property name="maxPoolSize" value="100"/>
<property name="minPoolSize" value="5"/>
<property name="maxIdleTime" value="30"/>
<property name="maxIdleTimeExcessConnections" value="30"/>
<property name="maxConnectionAge" value="30"/>
<property name="checkoutTimeout" value="100"/>
<property name="maxStatements" value="50"></property>
<property name="automaticTestTable" value="C3P0_TEST_TABLE"></property>
<property name="testConnectionOnCheckin" value="true"></property>
<property name="idleConnectionTestPeriod" value="30"></property>
</bean>
I'm also using TransactionManagement provided by spring - here is the configuration of that:
<!-- enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
Here is the rest of the datasource configuration:
<bean id="simpleJdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
<constructor-arg><ref bean="dataSource"/></constructor-arg>
</bean>
<bean id="userDAO" class="com.Test.dao.UserDAOImpl">
<property name="jdbcTemplate"><ref bean="jdbcTemplate"/></property>
</bean>
Finally here is a method where I update records into a database:
#Transactional(readOnly=false)
public void updateBenchMarkCumulative(List<BenchMarkCumulative> bmCumulativeList)
{
List<Object[]> parameters = new ArrayList<Object[]>();
for(BenchMarkCumulative bmCumulative : bmCumulativeList)
{
parameters.add(new Object[]{bmCumulative.getCumulativeAmt(), bmCumulative.getPkBenchMarkCumulative()});
}
this.simpleJdbcTemplate.batchUpdate(UPDATE_BENCHMARK_CUMULATIVE, parameters);
}
Is there something I'm doing wrong in my configuration or am I missing something that needs to be added to the configuration or coding?
Here is the exception being thrown:
INFO [http-8080-1] (AbstractPoolBackedDataSource.java510) - Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ java.beans.IntrospectionException: java.lang.reflect.InvocationTargetException [numThreadsAwaitingCheckoutDefaultUser] ]
org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections"
Thank you in advance.
Keith

I would agree with axtavt. I was in a similar situation, and there were couple places I was manually opening connections but not closing them (stored procedure calls for iSeries). Please verify if you have that kind of spots.

Related

Spring JDBC No suitable driver found for jdbc:jtds:sqlserver

Hi I am trying to connect SQL Server with JDBC JTDS but it turn out an error: No suitable driver found for jdbc:jtds:sqlserver, I already put it in my dependency and it appear on the Maven library, this is my configure for datasource:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:jtds:sqlserver://localhost/mkyongjava;instance=SQLEXPRESS" />
<property name="username" value="sa" />
<property name="password" value="admin123" />
</bean>
I already put jtds driver on Tomcat Server but no thing change
This is my project stuture
You are still providing the MySQL driver class name in the driverClassName property - try changing that to:
<property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver" />

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.

Make hibernate point to the same DB connection as DBUnit

I am using hiberante jpa to connect to a mysql database.
My persistence-unit in my persistence.xml looks like this:
<persistence-unit name="inventoryManager">
<!--some settings-->
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/inventory?useSSL=false&useUnicode=true&useJDBCCompliantTimezoneS‌​hift=true&useLegacyDatetimeCode=false&serverTimezone=UTC"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="1234"/>
<!--Hibernate properties-->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.format_sql" value="false"/>
<property name="hibernate.hbm2ddl.auto" value="validate"/>
</properties>
</persistence-unit>
My DAO´s are using this connection to execute all the operations with the database.
I am also using DBUnit for the tests, but I am using an in-memory database(hsql). and its configuration in my test case constructor looks like this:
System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS, "org.hsqldb.jdbcDriver" );
System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_CONNECTION_URL, "jdbc:hsqldb:mem:db" );
System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME, "sa" );
System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD, "" );
System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_SCHEMA, "db" );
So when I run a test that calls one DAO. The DAO instantiates an entityManager which points to the mysql connetion specified in the persistence.xml
The question is: How do I make the entityManager inside my DAO to point to my in-memory database?
Thanks in advance!
As you are not using Spring you can try a Maven based solution. This involves creating a separate persistence.xml under src/test/resources/META-INF with the relevant properties.
When running your tests this persistence.xml should take precedence over the one in src/main/resources.
You can do something like below:
1.Create a datasource bean pointing to In Memory DB something like below
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="org.hsqldb.jdbc.JDBCDriver" />
<property name="jdbcUrl"
value="jdbc:hsqldb:file:/data/data.db" />
</bean>
2.Define a EntityManagerFactory which will refer to this DataSource.
3.Add both these beans in a testConfig.xml
4.Run with JUnit
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations ={ "testconfig.xml" })

Tomcat creates new database session on every start + mysql

I am developing a web application and my stack is Mysql+ hibernate+ spring. I noticed that each time i start my tomcat a new database session is created.
my application.context xml has the following configuration
<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
<property name="driverClassName" value="${database.driverClassName}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
<property name="testOnBorrow" value="true"/>
<property name="testOnReturn" value="true"/>
<property name="testWhileIdle" value="true"/>
<property name="timeBetweenEvictionRunsMillis" value="1800000"/>
<property name="numTestsPerEvictionRun" value="3"/>
<property name="minEvictableIdleTimeMillis" value="1800000"/>
<property name="validationQuery" value="SELECT 1"/>
<property name="maxActive" value="15" />
<property name="removeAbandoned" value="true" />
<property name="removeAbandonedTimeout" value="60" />
<property name="logAbandoned" value="true" />
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
Any help is much appreciated
There could be two possibilities.
Either your application is executing queries on start up. This can be verified by turning on hibernate/spring logging.
The default minIdle/initialSize connection property of the connection pool is 1. Initial size refers to the initial number of connections created when the pool is started while minIdle refers minimum number of connections that can remain idle in the pool, without extra ones being created

About c3p0 and hibernate

I write a hibernate.cfg.xml file almost the same from hibernate books like:
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="hibernate.connection.password">**</property>
<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/db</property>
<property name="hibernate.connection.username">**</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.cache.use_second_level_cache">false</property>
<property name="hibernate.cache.use_query_cache">false</property>
<property name="c3p0.min_size">5</property>
<property name="c3p0.max_size">30</property>
<property name="c3p0.time_out">1800</property>
<property name="c3p0.max_statement">50</property>
<!--property name="show_sql">true</property-->
<property name="format_sql"> true</property>
But this seems actually c3p0 is not used. When I do test to establish 1000 sessions, it tries to establish 1000 connections.
Could anyone please give me some hint about this?
Thank you
Looking at your configuration file seems that you are missing one key property
<property name="connection.provider_class">
org.hibernate.connection.C3P0ConnectionProvider
</property>
Try setting this property and see if this turns things around for you or not.