jdbc connection string with c3p0 - java

I have jdbc configured with c3p0.
However, I am worried about possible conflicts, since some of the parameters in jdbc string and c3p0 are similar.
Here is my jdbc string:
jdbc:mysql://1.1.1.1:3306/db?useSSL=true&requireSSL=true&connectTimeout=15000&socketTimeout=30000&autoReconnect=true
We decided to include connectTimeout, socketTimeout, autoReconnect
because otherwise it took too long to switch to the replica if master crashes. ( We are using MySQL RDS Multi-AZ ).
Here are my c3p0 properties:
<property name="acquireIncrement" value="3"/>
<property name="minPoolSize" value="5"/>
<property name="maxPoolSize" value="10"/>
<property name="maxIdleTime" value="3600"/>
<!-- 1 hour -->
<property name="maxConnectionAge" value="7200"/>
<property name="maxIdleTimeExcessConnections" value="600"/>
<property name="idleConnectionTestPeriod" value="180"/>
<property name="testConnectionOnCheckin" value="true"/>
<property name="testConnectionOnCheckout" value="false"/>
Any ideas / suggestions?
Maybe someone has production-ready configuration?
Best Regards,
Maksim

Related

Queries take too long after MySQL fail-over

I have an application that uses MySQL fail-over via a connection url:
jdbc:mysql://172.17.0.4:3306,172.17.0.3:3306/db_name?autoReconnect=true&failOverReadOnly=false
Now when primary db is down then it should move to secondary connection and application flow should work as expected.
Now the problem happens when moving to secondary db. It takes too long to move/execute the queries, causing the flow to take much longer than expected.
I have checked already with db and there's no slow query issues. I guess it's something to do with fail-over and with checking the states. So, any idea what might be causing this issue or how to resolve this delay?
I am also using c3p0 to manage the connections pools. Already tried with initialTimeout and maxReconnects but no luck so far.
DataSource
<bean id="productionDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="description" value="integration_ds"/>
<!-- configuration pool via c3p0-->
<property name="acquireIncrement" value="${datasource.acquireIncrement}"/>
<property name="idleConnectionTestPeriod" value="${datasource.idleConnectionTestPeriod}"/>
<!-- seconds -->
<property name="maxPoolSize" value="${datasource.maxPoolSize}"/>
<property name="maxStatements" value="${datasource.maxStatements}"/>
<property name="maxStatementsPerConnection" value="${datasource.maxStatementsPerConnection}"/>
<property name="minPoolSize" value="${datasource.minPoolSize}"/>
<property name="initialPoolSize" value="${datasource.initialPoolSize}"/>
<property name="maxIdleTime" value="${datasource.maxIdleTime}"/>
<property name="acquireRetryAttempts" value="${datasource.acquireRetryAttempts}"/>
<property name="acquireRetryDelay" value="${datasource.acquireRetryDelay}"/>
<property name="breakAfterAcquireFailure" value="${datasource.breakAfterAcquireFailure}"/>
<property name="debugUnreturnedConnectionStackTraces" value="true"/>
</bean>
Properties
datasource.acquireIncrement=1
datasource.idleConnectionTestPeriod=1000
datasource.maxPoolSize=10
datasource.maxStatements=600
datasource.minPoolSize=5
datasource.initialPoolSize=5
datasource.maxIdleTime=7200
#datasource.acquireRetryAttempts=5
datasource.acquireRetryAttempts=1
#datasource.acquireRetryDelay=5000
#datasource.acquireRetryDelay=1000
datasource.acquireRetryDelay=100
datasource.breakAfterAcquireFailure=false
datasource.maxStatementsPerConnection=3
datasource.checkoutTimeout=100
DAO
private static final String findByAppIdHql = "select app from AppImpl app where app.appId = ?";
final Query query = sf.getCurrentSession().createQuery(findByAppIdHql).setString(0, appId);
query.setCacheable(true);
query.setCacheRegion("app_query_cache");
query.setCacheMode(CacheMode.NORMAL);
List<App> apps = query.list();

Spring Throws "ERROR SqlExceptionHelper: Already closed" after timeout

I have a spring application hosted on to the server (Tomcat 8.5). It goes idle if no one uses it. I already knew that timeout will occur if the DB is in idle state for 8 hours (Default timeout of MySQL). As mentioned in Spring Autoreconnect and Connection lost overnight post i have tried the solution available here.I have tried configuring application.properties but that doesn't bring any solution to the problem.
(PS:I'm not changing anything other than application.properties in my Spring Application).
Well if this
spring.datasource.testWhileIdle = true
spring.datasource.timeBetweenEvictionRunsMillis = 60000
spring.datasource.validationQuery = SELECT 1
or this
spring.datasource.testOnBorrow=true
spring.datasource.validationQuery=SELECT 1
didnt work maybe try this
Post SpringBoot 1.4 names have changed
They have defined new specific namespaces for the four connections pools spring supports: tomcat, hikari, dbcp, dbcp2.
spring.datasource.tomcat.testOnBorrow=true
spring.datasource.tomcat.validationQuery=SELECT 1
If problem doesn't solve even after including properties as in application.properties, Then problem will be solved when including testOnBorrow,validationQuery in application-context.xml located in src/main/resources
<bean name="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${database.driver.classname}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
<property name="initialSize" value="2"/>
<property name="maxActive" value="50"/>
<property name="maxIdle" value="5"/>
<property name="maxWait" value="-1"/>
<property name="removeAbandoned" value="true"/>
<property name="removeAbandonedTimeout" value="600"/>
<property name="logAbandoned" value="true"/>
<property name="testOnBorrow" value="true" />
<property name="validationQuery" value="SELECT 1" />
</bean>
The solution is to validate connection thread when it is borrowed from thread pool by enabling testOnBorrow and providing validationQuery.

Hibernate: why c3p0 timeout not working?

I work on web java application using hibernate, and i always get memory low errors for tons of java inactive sessions on my oracle db. i tried to closing this unused sessions with c3p0 timeout config but it's not working at all.
this is my hibernate config and my open sessions after several minutes:
(the commented code below is for when i tried using common dbcp refer to one of answers for similar questions and timeout times set to 30 seconds for test.)
<property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>
<property name="hibernate.connection.driver_class">oracle.jdbc.OracleDriver</property>
<property name="hibernate.connection.url">jdbc:oracle:thin:#localhost:test</property>
<property name="hibernate.connection.username">tams_test</property>
<property name="hibernate.connection.password">test1234</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<property name="hibernate.connection.isolation">2</property>
<property name="org.hibernate.flushMode">COMMIT</property>
<property name="hibernate.cache.use_query_cache">false</property>
<property name="hibernate.transaction.auto_close_session">true</property>
<property name="hibernate.order_updates">true</property>
<property name="hibernate.order_inserts">true</property>
<!-- <property name="hibernate.dbcp.initialSize">3</property>
<property name="hibernate.dbcp.maxIdle">50</property>
<property name="hibernate.dbcp.minIdle">0</property>
<property name="hibernate.dbcp.maxWait">180000</property>
<property name="hibernate.dbcp.maxConnLifetimeMillis">30000</property>
<property name="hibernate.dbcp.defaultQueryTimeout">1</property>-->
<property name="hibernate.c3p0.min_size">1</property>
<property name="hibernate.c3p0.max_size">150</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.timeout">30</property>
<property name="hibernate.c3p0.idle_test_period">30</property>
<property name="hibernate.c3p0.idleConnectionTestPeriod">30</property>
<property name="c3p0.testConnectionOnCheckout">true</property>
<property name="testConnectionOnCheckin">true</property>
<property name="c3p0.maxConnectionAge">30</property>
<property name="maxIdleTimeExcessConnections">30</property>
<property name="connection.provider_class">
org.hibernate.connection.C3P0ConnectionProvider
</property>
open sessions on oracle db after several minutes
I faced your problem too, and hibernate didn't want to apply my parameters of c3p0, so I changed my datasource and it completly solved my problem of inactive sessions.
Try to setup your dataSource bean like this:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/>
<property name="jdbcUrl" value="jdbc:oracle:thin:#xxxx:1521:xxx"/>
<property name="user" value="xx"/>
<property name="password" value="xxxx"/>
<property name="maxStatements" value="1000"/>
<property name="maxIdleTime" value="30"/>
<property name="maxPoolSize" value="100"/>
<property name="minPoolSize" value="10"/>
<property name="initialPoolSize" value="10"/>
<property name="idleConnectionTestPeriod" value="20"/>
</bean>

HikariCP - Idle Timout property is not overriding

Inspite of overriding the HikariCP idleTimeout property "hibernate.hikari.idleTimeout", connection is not releasing after threshold. I am using sql command SHOW FULL PROCESSLIST to analyze the connections.
<property name="hibernate.hikari.dataSource.url" value="${DATABASE_URL}"/>
<property name="hibernate.hikari.dataSource.user" value="${DATABASE_USERNAME}"/>
<property name="hibernate.hikari.dataSource.password" value="${DATABASE_PASSWORD}"/>
<property name="hibernate.hikari.dataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlDataSource"/>
<property name="hibernate.connection.provider_class" value="com.zaxxer.hikari.hibernate.HikariConnectionProvider"/>
<property name="hibernate.hikari.maxLifetime" value="1800000"/>
<property name="hibernate.hikari.idleTimeout" value="60000"/>
<property name="hibernate.hikari.connectionTimeout" value="180000" />
<property name="hibernate.hikari.maximumPoolSize" value="10"/>
<property name="hibernate.hikari.minimumIdle" value="5"/>
Is the - at the end of hibernate.hikari.maxLifetime causing you problems?
<property name="hibernate.hikari.maxLifetime" value="1800000"/> -

Connection pooling in spring jdbc

I have implemented spring jdbc in my project. I am just curious to know how connection pooling in handled in spring jdbc? If spring is taking care of connections, then where can I specify the max number of connections allowed for my application?
Another question is how is connection pooling handled in simple jdbc.
Please clarify.
You can use own custom datasource, like this:
<bean id="springDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" >
<property name="url" value="jdbc:oracle:thin:#localhost:1521:SPRING_TEST" />
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="username" value="root" />
<property name="password" value="root" />
<property name="removeAbandoned" value="true"/>
<property name="initialSize" value="20" />
<property name="maxActive" value="30" />
</bean>
//Dao class configuration in spring
<bean id="EmployeeDatabaseBean" class="com.test.EmployeeDAOImpl">
<property name="dataSource" ref="springDataSource"/>
</bean>
Official documentation
Here or here described pretty simple.

Categories