Hibernate: why c3p0 timeout not working? - java

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>

Related

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"/> -

Advantage of org.springframework.jdbc.datasource.DriverManagerDataSource over oracle.jdbc.pool.OracleDataSource

I currently use this configuration for my projects:
<bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource"
destroy-method="close">
<property name="URL" ...
<property name="user" ...
<property name="password" ...
<property name="connectionCachingEnabled" value="true" />
And it works fine, pretty fast.
I happened to see, on an old project (spring 2.5) this configuration:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url"...
<property name="username" ...
<property name="password" ...
</bean>
From documentation it would seem that this last option does not make use of a connection pool. I see no reason to use this configuration over mine, but it still exists so I am curious: where's the advantage/limitation?
1st configuration is oracle specific, whereas 2nd configuration is generic. You can explicitly define driver class.
This is the only major difference I can see in them other than connection pool support of OracleDataSource.
You can use it for generic behavior as mentioned below:
<bean id="baseDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
abstract="true">
<property name="username" value="user"/>
<property name="password" value="pwd" />
</bean>
<bean id="mySqlDataSource" parent="baseDataSource">
<property name="driverClassName" value="${mySQL.driver}" />
<property name="url" value="${mySQL.url}"/>
</bean>
<bean id="oracleDataSource" parent="baseDataSource">
<property name="driverClassName" value="${oracle.driver}" />
<property name="url" value="${oracle.url}"/>
</bean>
Property values you can externalized.
You can explore Apache Jakarta Commons DBCP which has all the features of DriverManagerDataSource
along with connection pool feature.

Connect to IPv6 mysql using java

I am using org.springframework.version -- >3.1.0.RELEASE and my datasource is like below
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" scope="prototype">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="username" value="test"/>
<property name="password" value="test123"/>
<property name="maxActive" value="100"/>
<property name="maxIdle" value="30"/>
<property name="maxWait" value="16000"/>
<property name="timeBetweenEvictionRunsMillis" value="30000"/>
<property name="minEvictableIdleTimeMillis" value="60000"/>
<property name="testOnBorrow" value="true"/>
<property name="validationQuery" value="SELECT 1"/>
</bean>
Here is below code to create jdbctemplate...
BasicDataSource bds = (BasicDataSource) ctx.getBean("dataSource");
bds.setUrl("jdbc:mysql://address=(protocol=tcp)(host=xx.xx.xx.xx)(port=3306 )/" + db + "?autoreconnect=true);
JdbcTemplate jt = new JdbcTemplate(bds);
I searched and this the url suggested to connect to IPv6 address. I am able to connect thro DriverManager.getConnection but not thro this datasource....Am i missing anything here
Exception
Caused by: java.net.UnknownHostException: address=(protocol=tcp)(host=xx.xx.xx.xx)
at java.net.InetAddress.getAllByName0(InetAddress.jav a:1215)
at java.net.InetAddress.getAllByName(InetAddress.java :1127)
at java.net.InetAddress.getAllByName(InetAddress.java :1063)
at com.mysql.jdbc.StandardSocketFactory.connect(Stand ardSocketFactory.java:243)
I am using Centos-6.2 x86_64, I have checked the /etc/hosts and everything looks fine.

The configuration for com.mchange.v2.c3p0.ComboPooledDataSource

I am looking for help with configuration of my data source type com.mchange.v2.c3p0.ComboPooledDataSource
I need to have 1000 database connections available concurrently.
I started with following configuration and tried to increase the number for initialPoolSize, maxPoolSize, minPoolSize but it doesn’t work.
<bean id="dataSource" destroy-method="close" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="someUrl"/>
<property name="user" value="someUser"/>
<property name="password" value="somePass"/>
<property name="acquireIncrement" value="1" />
<property name="acquireRetryAttempts" value="3"/>
<property name="acquireRetryDelay" value="300" />
<property name="initialPoolSize" value=“3" />
<property name="maxPoolSize" value="10" />
<property name="minPoolSize" value=“3" />
</bean>

Configure spring datasource for hibernate and #Transactional

At this moment I'm using DriverManagerDataSource with #Transactional annotation to manage transactions. But all transactions are very very slow, probably because data source open and close connection to db each time.
What data source should I use to speed up transaction?
I am using in my application combination of two approaches. the first one is c3p0 connection pooling, its almost the same solution as chkal sugested. The second approach is to use Spring lazyConnectionDataSourceProxy, which creates lazy loading proxy that loads connection only if you hit the database. This is very useful, when you have second level cache and you are only reading cached data and queries - database wont be hit, and you don't need to acquire connection (which is pretty expensive).
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- Pool properties -->
<property name="minPoolSize" value="5" />
<property name="initialPoolSize" value="10" />
<property name="maxPoolSize" value="50" />
<property name="maxStatements" value="50" />
<property name="idleConnectionTestPeriod" value="120" />
<property name="maxIdleTime" value="1200" />
</bean>
<bean name="lazyConnectionDataSourceProxy" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
<property name="targetDataSource" ref="dataSource" />
</bean>
DriverManagerDataSource isn't actually a connection pool and should only be used for testing. You should try BasicDataSource from Apache Commons DBCP. Something like:
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>

Categories